package net.northking.cctp.element.ats.keywords;


import cn.hutool.core.util.ReUtil;
import com.alibaba.fastjson.JSONObject;
import net.northking.cctp.element.ats.dto.AtsScenarioExecute;
import net.northking.cctp.element.ats.dto.ResultResponse;
import net.northking.cctp.element.ats.utils.HttpClientUtils;
import net.northking.cctp.element.ats.utils.SnowflakeIdGenerator;
import net.northking.cctp.element.core.IExecuteContext;
import net.northking.cctp.element.core.annotation.Argument;
import net.northking.cctp.element.core.annotation.Keyword;
import net.northking.cctp.element.core.annotation.Keywords;
import net.northking.cctp.element.core.type.DataType;
import net.northking.cctp.element.core.type.ParamScope;
import org.apache.commons.collections4.map.HashedMap;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.*;
import org.springframework.web.client.RestTemplate;

import java.util.Map;


@Keywords
public class AtsInterfaceTools {

    /**
     * 日志
     */
    private final static Logger logger = LoggerFactory.getLogger(AtsInterfaceTools.class);


    /**
     * <p>执行请求ats接口</p>
     * Example:
     *
     * @param projectId 项目id
     * @param scriptId
     * @return hash表
     */
    @Keyword(alias = "ATS接口组件", category = "0", attributes = "-1")
    public String atsRequest(
            @Argument(name = "atsUrl", comment = "http接口地址", type = DataType.STRING,hideSensitive = true) String atsUrl,
            @Argument(name = "ak", comment = "接口验证ak", type = DataType.STRING,hideSensitive = true) String ak,
            @Argument(name = "projectId", comment = "项目id", type = DataType.STRING) String projectId,
            @Argument(name = "scriptId", comment = "脚本id", type = DataType.STRING) String scriptId,
            @Argument(name = "environmentId", comment = "执行环境id", type = DataType.STRING) String environmentId,
            @Argument(name = "environmentGroupId", comment = "环境组别id", type = DataType.STRING) String environmentGroupId,
            @Argument(name = "executionService", comment = "执行机组编码", type = DataType.STRING) String executionService,
            @Argument(name = "type", comment = "UI调用类型", type = DataType.STRING) String type,
            @Argument(name = "uiScriptName", comment = "组件名称", type = DataType.STRING) String uiScriptName,
            @Argument(name = "executorName", comment = "执行人名称", type = DataType.STRING) String executorName,
            @Argument(name = "mode", comment = "单接口:1;场景:2", type = DataType.INTEGER) Integer mode,
            @Argument(name = "dataSetId", comment = "数据集id", type = DataType.STRING) String dataSetId,
            @Argument(name = "cycleId", comment = "轮次id", type = DataType.STRING) String cycleId,
            @Argument(name = "value", comment = "组件返回值", type = DataType.STRING, scope = ParamScope.OUTPUT, defaultValue = "") String value,
            IExecuteContext executeContext) {
        String result = "";
        if (StringUtils.isBlank(atsUrl) || StringUtils.isBlank(ak)) {
            result = "nacos配置没有获取到，请联系系统维护人员";
        } else {
            AtsScenarioExecute scenarioExecute = new AtsScenarioExecute();
            SnowflakeIdGenerator snowflake = new SnowflakeIdGenerator(0L, 0L);

            String executeKey = "UI_AUTO_" + snowflake.nextId();
            scenarioExecute.setExecutionKey(executeKey);
            scenarioExecute.setProjectId(projectId);
            scenarioExecute.setScriptId(scriptId);
            if (StringUtils.isNotBlank(environmentGroupId) && !environmentGroupId.equals("0")) {
                scenarioExecute.setEnvironmentGroupId(environmentGroupId);
            }
            if (StringUtils.isNotBlank(environmentId) && !environmentId.equals("0")) {
                scenarioExecute.setEnvironmentId(environmentId);
            }
            if (StringUtils.isNotBlank(dataSetId) && !dataSetId.equals("0")) {
                scenarioExecute.setDataSetId(dataSetId);
            }
            if (StringUtils.isNotBlank(cycleId) && !cycleId.equals("0")) {
                scenarioExecute.setCycleId(cycleId);
            }
            scenarioExecute.setExecutionService(executionService);
            scenarioExecute.setType(type);
            scenarioExecute.setUiScriptName(uiScriptName);
            scenarioExecute.setExecutorName(executorName);
            cn.hutool.json.JSONObject jsonObject = new cn.hutool.json.JSONObject(scenarioExecute);
            String doPost = null;
            if (mode == 1) {
                doPost = HttpClientUtils.doPost(atsUrl + "/interface-test/in/ui/executeTestScript", jsonObject.toString(), ak);

            }
            if (mode == 2) {
                doPost = HttpClientUtils.doPost(atsUrl + "/interface-test/in/ui/executeScenario", jsonObject.toString(), ak);

            }
            JSONObject parseObject = JSONObject.parseObject(doPost);
            ResultResponse response = parseObject.toJavaObject(ResultResponse.class);
            System.out.println(response);
            if (!response.getCode().equals("success")) {
                result = com.alibaba.fastjson.JSON.toJSONString(response);
            } else {
                RestTemplate restTemplate = new RestTemplate();
                ResultResponse resultResponse = new ResultResponse();
                ResponseEntity<String> exchange = null;
                String executeStatus = "";
                int num = 0;
                while (!executeStatus.equals("1") && num < 30 && !executeStatus.equals("2")) {
                    try {
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    String url = "http://localhost:6001/v1/getRedisKey/{key}";
                    HttpHeaders headers = new HttpHeaders();
                    headers.set("Content-Type", "application/json");
                    HttpEntity requestEntity = new HttpEntity(headers);
                    Map<String, String> mapRequest = new HashedMap<>();
                    mapRequest.put("key", executeKey);
                    exchange = restTemplate.exchange(url, HttpMethod.GET, requestEntity, String.class, mapRequest);
                    if (exchange != null) {

                        JSONObject parse = JSONObject.parseObject(exchange.getBody());
                        resultResponse = parse.toJavaObject(ResultResponse.class);
                        try {
                            Map<String, String> map = (Map) resultResponse.getData();
                            if (map.size() > 0) {
                                executeStatus = String.valueOf(map.get("executeStatus"));
                            }
                        }catch (Exception e){
                            logger.error("执行机redis没有获取到结果", e);
                        }
                    }
                    num++;

                }
                if (executeStatus.equals("2")) {
                    resultResponse.setMessage("执行失败");
                    result = com.alibaba.fastjson.JSON.toJSONString(resultResponse);
                } else if (num >= 30 && !executeStatus.equals("1")) {
                    resultResponse.setMessage("接口执行时间过长,已自动断开");
                    result = com.alibaba.fastjson.JSON.toJSONString(resultResponse);
                } else {
                    result = com.alibaba.fastjson.JSON.toJSONString(resultResponse);
                }
            }
        }
        save2ContentText(value, executeContext, result);
        return result;
    }

    public static void save2ContentText(String value, IExecuteContext executeContext, Object s) {
        //将值塞入到组件返回值中
        if(value==null){
            return;
        }
        if (value.contains("#{") && value.contains("}")) {
            String keyValue = ReUtil.get("(?<=\\#\\{)(.+?)(?=\\})", value, 1);
            // #{} 全局变量
            executeContext.setProjectGlobalVariable(keyValue, null == s ? "" : s.toString());
        }
        if (value.contains("${") && value.contains("}")) {
            String keyValue = ReUtil.get("(?<=\\$\\{)(.+?)(?=\\})", value, 1);
            // ${} 全局变量
            executeContext.setVariable(keyValue, null == s ? "" : s.toString());
        }
    }
}




