package net.educoder.ecsonar.task;

import com.alibaba.fastjson.JSONObject;
import net.educoder.ecsonar.constant.Constant;
import net.educoder.ecsonar.model.GraduationProjectTaskInfoDetail;
import net.educoder.ecsonar.model.SonarScannerParam;
import net.educoder.ecsonar.services.DbOperateService;
import net.educoder.ecsonar.services.SonarService;
import net.educoder.ecsonar.utils.SystemUtil;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;


/**
 * @Author: youys
 * @Date: 2023/8/31
 * @Description: 毕业设计质量检测任务
 */
public class GraduationProjectQualityInspectRunnable implements Runnable {


    private static final Logger LOGGER = LoggerFactory.getLogger(GraduationProjectQualityInspectRunnable.class);

    private String taskId;

    public String language;

    private ExecutorService queryResultPool;
    private GraduationProjectTaskInfoDetail taskInfoDetail;
    private DbOperateService dbOperateService;
    private SonarService sonarService;

    private static final String SUCCESS = "SUCCESS";

    public GraduationProjectQualityInspectRunnable(String taskId, String language,
                                                   GraduationProjectTaskInfoDetail taskInfoDetail,
                                                   ExecutorService queryResultPool) {
        this.taskId = taskId;
        this.language = language;
        this.taskInfoDetail = taskInfoDetail;
        this.queryResultPool = queryResultPool;
    }


    @Override
    public void run() {
        String projectName = taskInfoDetail.getProjectName();
        String path = String.format("/tmp/%s/%s/", taskId, projectName);

        // 需要先git clone 到某个目录下面
        SystemUtil.ExecuteResp executeResp = gitClone(path, taskInfoDetail.getGitUrl());
        if (executeResp.getStatus() != 0) {
            LOGGER.warn("projectName:{} git clone失败", taskInfoDetail.getProjectName());
            return;
        }

        // 写完所有文件开始用sonar进行质量分析
        SonarScannerParam param = new SonarScannerParam(projectName, path);
        if (Constant.C.equalsIgnoreCase(language) || Constant.CXX.equalsIgnoreCase(language)) {
            String resultPath = String.format("/tmp/%s", taskId);
            File f = new File(resultPath);
            if (!f.exists()) {
                f.mkdirs();
            }
            param.setCppCheckReportPath(resultPath + String.format("/%s-result.xml", projectName));

        }
        // 调用sonar服务
        LOGGER.info("taskId:{}, projectName:{}, detailId:{} 开始调用sonar分析,语言:{}", taskId, projectName, taskInfoDetail.getId(), language);
        // sonarUrl 启动多个，随机一个
        sonarService.sonar(language, param);

        // 提交一个查结果的任务
        GraduationProjectQueryResultRunnable queryResultRunnable = new GraduationProjectQueryResultRunnable(projectName, taskInfoDetail.getId(), dbOperateService);
        LOGGER.info("taskId:{}, projectName:{}, detailId:{} 提交了查询结果的任务", taskId, projectName, taskInfoDetail.getId());
        Future<String> submit = queryResultPool.submit(queryResultRunnable);
        String status;
        try {
            status = submit.get();
        } catch (Exception e) {
            LOGGER.error("GraduationProjectQueryResultRunnable is Exception", e);
            status = "FAILED";
        }
        dbOperateService.updateGraduationProjectTaskInfoDetail(taskInfoDetail.getId(), SUCCESS.equals(status) ? 1 : -1);
    }



    public void setDbOperateService(DbOperateService dbOperateService) {
        this.dbOperateService = dbOperateService;
    }

    public void setSonarService(SonarService sonarService) {
        this.sonarService = sonarService;
    }

    /**
     * 克隆代码
     *
     * @param path
     * @param gitUrl
     * @return
     */
    private SystemUtil.ExecuteResp gitClone(String path, String gitUrl) {

        String command = StringUtils.join("rm -rf ", path, " && mkdir -p ", path, " && cd ", path, " && git clone ", gitUrl);

        LOGGER.info("git clone：command:{}", command);
        SystemUtil.ExecuteResp executeResp = SystemUtil.executeAndGetExitStatus(command);

        LOGGER.info("git clone结果:{}", JSONObject.toJSONString(executeResp));
        return executeResp;
    }
}
