package org.matrix.testNg;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.extern.slf4j.Slf4j;
import org.matrix.BaseBootApplication;
import org.matrix.actuators.checkpoint.CheckPointActuator;
import org.matrix.actuators.httpclient.HttpClientActuator;
import org.matrix.actuators.usecase.CaseActuator;
import org.matrix.actuators.usecase.TestCaseExecuteResult;
import org.matrix.database.entity.TestCase;
import org.matrix.database.entity.TestCaseListDataBto;
import org.matrix.database.entity.TestData;
import org.matrix.database.service.ITestCaseService;
import org.matrix.database.service.ITestDataService;
import org.matrix.exception.GlobalException;
import org.matrix.socket.vo.CaseExecuteVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.stereotype.Component;
import org.springframework.test.context.testng.AbstractTestNGSpringContextTests;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Parameters;
import org.testng.annotations.Test;

import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * @author mry
 */
@Slf4j
@Component
@SpringBootTest(classes = BaseBootApplication.class)
public class TestPigeon extends AbstractTestNGSpringContextTests {

    String sql;
    Long envId;
    Long projectId;

    @Value("${spring.datasource.dynamic.datasource.master.driverClassName}")
    private String driver;

    @Value("${spring.datasource.dynamic.datasource.master.url}")
    private String url;

    @Value("${spring.datasource.dynamic.datasource.master.username}")
    private String username;

    @Value("${spring.datasource.dynamic.datasource.master.password}")
    private String password;

    @Autowired
    private ITestCaseService caseService;

    @Autowired
    private ITestDataService dataService;

    @Autowired
    private CheckPointActuator checkPointActuator;

    @Autowired
    private HttpClientActuator httpClientActuator;

    @Autowired
    private CaseActuator caseActuator;

    @Parameters({"sql", "envId", "projectId"})
    @BeforeClass
    public void beforeClass(String sql, Long envId, Long projectId) {
        this.sql = sql;
        this.envId = envId;
        this.projectId = projectId;
    }


    /**
     * XML中的SQL决定了执行什么用例, 执行多少条用例, SQL的搜索结果为需要测试的测试用例
     */
    @DataProvider(name = "testData")
    private Iterator<Object[]> getData() {
        return new DataProviderForDb(driver, url, username, password, sql);
    }

    public static Map<Long, Map<Long, List<TestCaseExecuteResult>>> userResultMap = new HashMap<>();
    public static Map<Long, List<TestCaseExecuteResult>> resultMap = new HashMap<>();

    @Test(dataProvider = "testData")
    public void test(Map<String, String> data) {
        log.info("这是testData");
        String id = data.get("id");
        long caseId = Long.parseLong(id);
        TestCase testCase = java.util.Optional.of(caseService.getById(caseId))
                .orElseThrow(() -> new GlobalException(String.format("没有找到id = %d 的TestCase", caseId)));
        List<TestData> testDataList = java.util.Optional.of(dataService.list(Wrappers.lambdaQuery(TestData.class)
                        .eq(TestData::getTestCaseId, caseId)))
                .orElseThrow(() -> new GlobalException(String.format("没有找到testCaseId = %d 的TestData", caseId)));
        CaseExecuteVo caseExecuteVo = new CaseExecuteVo();
        caseExecuteVo.setProjectId(testCase.getProjectId());
        caseExecuteVo.setEnvId(envId);
        caseExecuteVo.setUserId(1L);
        caseExecuteVo.getTestCaseListDataBtoList().add(
                new TestCaseListDataBto(
                        testCase,
                        testDataList
                )
        );
        List<TestCaseExecuteResult> testCaseExecuteResults = caseActuator.runTestCase(null, caseExecuteVo);
        resultMap.put(caseId, testCaseExecuteResults);
        userResultMap.put(1L, resultMap);
    }


}
