package org.matrix.testNg.xml.reportXml;

import lombok.extern.slf4j.Slf4j;
import org.matrix.actuators.checkpoint.CheckPointResult;
import org.matrix.actuators.usecase.TestDataExecuteResult;
import org.matrix.database.entity.TestCase;
import org.matrix.database.service.ITestCaseService;
import org.matrix.exception.GlobalException;
import org.matrix.util.ReporterUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.testng.*;

import java.util.*;

/**
 * @author mruny
 */
@Slf4j
@Component
public class ReporterData {

    private static ITestCaseService testCaseService;

    @Autowired
    private void setITestDataService(ITestCaseService testCaseService) {
        ReporterData.testCaseService = testCaseService;
    }

    //测试结果Set<ITestResult>转为list，再按执行时间排序 ，返回list
    public List<ITestResult> sortByTime(Set<ITestResult> str) {
        List<ITestResult> list = new ArrayList<ITestResult>();
        for (ITestResult r : str) {
            list.add(r);
        }
        Collections.sort(list);
        return list;
    }

    //模板中的公共部分
    public DataBean testContext(ITestContext context) {
        // 测试结果汇总数据
        DataBean data = new DataBean();
        ReportUnits units = new ReportUnits();
        //通过,失败,跳过的测试用例
        IResultMap passedTests = context.getPassedTests();
        IResultMap failedTests = context.getFailedTests();
        IResultMap skipedTests = context.getSkippedTests();
        Collection<ITestNGMethod> excludeTests = context.getExcludedMethods();
        int passedTestsSize = passedTests.size();
        int failedTestsSize = failedTests.size();
        int skipedTestsSize = skipedTests.size();
        int excludeTestsSize = excludeTests.size();
        //所有测试结果的数量＝测试pass+fail+skip的和，因为数据驱动一个测试方法有多次执行的可能，导致方法总数并不等于测试总数
        int allTestsSize = passedTestsSize + failedTestsSize + skipedTestsSize;
        data.setAllTestsSize(allTestsSize);
        data.setPassedTestsSize(passedTestsSize);
        data.setFailedTestsSize(failedTestsSize);
        data.setSkippedTestsSize(skipedTestsSize);
        data.setExcludeTestsSize(excludeTestsSize);
        data.setTestsTime(units.getTestDuration(context));
        data.setPassPercent(units.formatPercentage(passedTestsSize, allTestsSize));
        return data;
    }

    //每条测试用例的细节
    public List<DataBean> testResults(IResultMap map, int status) {
        DataBean data = new DataBean();
        // 测试结果详细数据
        List<DataBean> list = new ArrayList<DataBean>();
        //工具类
        ReportUnits units = new ReportUnits();
        for (ITestResult result : sortByTime(map.getAllResults())) {
            List<TestDataExecuteResult> testDataExecuteResults;
            Map<Long, List<TestDataExecuteResult>> longListMap = ReporterUtils.userResultMap.get(1L);
            Set<Long> longs = longListMap.keySet();
            for (Long caseId : longs) {
                TestCase testCase = java.util.Optional.of(testCaseService.getById(caseId))
                        .orElseThrow(() -> new GlobalException(String.format("没有找到id = %d 的TestCase", caseId)));
                testDataExecuteResults = ReporterUtils.resultMap.get(caseId);
                for (TestDataExecuteResult testDataExecuteResult : testDataExecuteResults) {
                    data.setDuration(units.formatDuration(result.getEndMillis()
                            - result.getStartMillis()));
                    data.setParams(units.getParams(result));
                    CheckPointResult checkPointResult = testDataExecuteResult.getCheckPointResult();
                    data.setTestCaseName(testCase.getName());
                    data.setOutput(Reporter.getOutput(result));
                    data.setDependMethod(units.getDependMethods(result));
                    data.setType(String.valueOf(testCase.getType()));
                    data.setDetail(testCase.getDetail());
                    data.setMoveBefore(testCase.getMoveBefore());
                    data.setMoveAfterCase(testCase.getMoveAfterCase());
                    data.setMoveAfterTest(testCase.getMoveAfterTest());
                    data.setDescription(testCase.getDes());
                    data.setResultMessage(checkPointResult);
                    data.setThrowable(result.getThrowable());
                    if (result.getThrowable() != null) {
                        data.setStackTrace(result.getThrowable().getStackTrace());
                    }
                }
            }
            list.add(data);
        }
        return list;
    }
}