package com.test.common.utils;

import com.test.common.core.domain.model.ErrorCodeStat;
import com.test.common.core.domain.model.HttpSample;
import com.test.common.core.domain.model.InterfaceErrorDetail;
import com.test.common.core.domain.model.InterfaceErrorStat;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author liangdaliang
 * @Description：Http采样分析工具类
 * @date 2025-04-17 19:01
 */
public class HttpSampleAnalyzer {
    private final List<HttpSample> samples;
    private final int totalRequests;

    public HttpSampleAnalyzer(List<HttpSample> samples) {
        this.samples = samples;
        this.totalRequests = samples.size();
    }

    /**
     * 需求1: 错误响应状态码统计
     * @return 错误状态码统计列表
     */
    public List<ErrorCodeStat> analyzeErrorCodes() {
        // 过滤出所有失败的请求
        List<HttpSample> errorSamples = samples.stream()
                .filter(s -> !s.getS())
                .collect(Collectors.toList());

        int totalErrors = errorSamples.size();

        // 按状态码分组统计
        Map<String, Long> codeCountMap = errorSamples.stream()
                .collect(Collectors.groupingBy(
                        HttpSample::getRc,
                        Collectors.counting()
                ));

        // 转换为包含比率的统计对象
        List<ErrorCodeStat> result = new ArrayList<>();
        codeCountMap.forEach((code, count) -> {
            double errorRatio = totalErrors == 0 ? 0 : (double) count / totalErrors * 100;
            double totalRatio = (double) count / totalRequests * 100;
            result.add(new ErrorCodeStat(code, count, errorRatio, totalRatio));
        });

        // 按错误数量降序排序
        result.sort((a, b) -> Long.compare(b.getCount(), a.getCount()));

        return result;
    }

    /**
     * 需求2: Top 5错误接口统计
     * @return Top 5错误接口列表
     */
    public List<InterfaceErrorStat> getTop5ErrorInterfaces() {
        // 获取所有接口的错误统计
        Map<String, InterfaceErrorStat> allInterfaceStats = getAllInterfacesErrorStats();

        // 按错误数量降序排序并取前5
        return allInterfaceStats.values().stream()
                .sorted((a, b) -> Long.compare(b.getErrorCount(), a.getErrorCount()))
                .limit(5)
                .collect(Collectors.toList());
    }

    /**
     * 需求3: 每个接口的错误码明细
     * @return 接口错误明细列表
     */
    public List<InterfaceErrorDetail> getInterfaceErrorDetails() {
        // 按接口名称分组
        Map<String, List<HttpSample>> samplesByInterface = samples.stream()
                .collect(Collectors.groupingBy(HttpSample::getLb));

        List<InterfaceErrorDetail> result = new ArrayList<>();

        samplesByInterface.forEach((interfaceName, interfaceSamples) -> {
            // 过滤出该接口的错误请求
            List<HttpSample> errorSamples = interfaceSamples.stream()
                    .filter(s -> !s.getS())
                    .collect(Collectors.toList());

            // 按错误码统计
            Map<String, Long> errorCodeCounts = errorSamples.stream()
                    .collect(Collectors.groupingBy(
                            HttpSample::getRc,
                            Collectors.counting()
                    ));

            if (!errorCodeCounts.isEmpty()) {
                result.add(new InterfaceErrorDetail(interfaceName, errorCodeCounts));
            }
        });

        return result;
    }

    // 辅助方法：获取所有接口的错误统计
    private Map<String, InterfaceErrorStat> getAllInterfacesErrorStats() {
        // 按接口名称分组
        Map<String, List<HttpSample>> samplesByInterface = samples.stream()
                .collect(Collectors.groupingBy(HttpSample::getLb));

        Map<String, InterfaceErrorStat> result = new HashMap<>();

        samplesByInterface.forEach((interfaceName, interfaceSamples) -> {
            long total = interfaceSamples.size();
            long errors = interfaceSamples.stream()
                    .filter(s -> !s.getS())
                    .count();

            result.put(interfaceName, new InterfaceErrorStat(interfaceName, total, errors));
        });

        return result;
    }
}
