package net.educoder.ecsonar.task;

import cn.hutool.core.io.FileUtil;
import net.educoder.ecsonar.constant.Constant;
import net.educoder.ecsonar.model.GameCodes;
import net.educoder.ecsonar.model.SonarScannerParam;
import net.educoder.ecsonar.model.TaskInfoDetail;
import net.educoder.ecsonar.model.vo.QualityInspectUserDataVO;
import net.educoder.ecsonar.services.DbOperateService;
import net.educoder.ecsonar.services.SonarService;
import org.apache.tomcat.util.http.fileupload.FileUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.List;
import java.util.concurrent.ExecutorService;


/**
 * @Author: youys
 * @Date: 2022/1/18
 * @Description: 教学课堂质量检测任务
 */
public class QualityInspectRunnable implements Runnable {


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

    private String taskId;
    public String language;
    public String homeworkId;
    private QualityInspectUserDataVO userData;

    private ExecutorService queryResultPool;

    private TaskInfoDetail taskInfoDetail;
    private DbOperateService dbOperateService;
    private SonarService sonarService;

    public QualityInspectRunnable(String taskId, String language, String homeworkId,
                                  TaskInfoDetail taskInfoDetail,
                                  QualityInspectUserDataVO userData,
                                  ExecutorService queryResultPool) {
        this.taskId = taskId;
        this.language = language;
        this.homeworkId = homeworkId;
        this.taskInfoDetail = taskInfoDetail;
        this.userData = userData;
        this.queryResultPool = queryResultPool;
    }


    @Override
    public void run() {
        String projectName = String.format("%s-%s", homeworkId, userData.getStudentId());
        String path = String.format("/tmp/%s/%s/", homeworkId, projectName);

        List<Long> codeIds = userData.getCodeIds();
        boolean constantCFlag = true,constantCPPFlag = true,constantJavaFlag = true, constantPyFlag = true;
        for (Long codeId : codeIds) {
            File file = new File(path);
            try {
                FileUtils.forceMkdir(file);
            } catch (IOException e) {
            }

            GameCodes gameCodes = dbOperateService.queryGameCodesById(codeId);
            if(gameCodes == null){
                LOGGER.error("projectName:{}, game_codes_id:{}找不到对应的学员代码",projectName, codeId);
                continue;
            }
            FileUtil.writeString(gameCodes.getCode(), path + gameCodes.getPath(), Charset.forName("UTF-8"));

            if (constantCFlag && gameCodes.getPath().toLowerCase().contains(".c")) {
                constantCFlag = false;
            } else if (constantCPPFlag && gameCodes.getPath().toLowerCase().contains(".cpp")) {
                constantCPPFlag = false;
            } else if (constantJavaFlag && gameCodes.getPath().toLowerCase().contains(".java")) {
                constantJavaFlag = false;
            } else if (constantPyFlag && gameCodes.getPath().toLowerCase().contains(".py")) {
                constantPyFlag = false;
            }
        }

        // 需要自己判别语言,Java优先
        if(!constantJavaFlag){
            language = Constant.JAVA;
        }else if(!constantPyFlag){
            language = Constant.PYTHON;
        } else if(!constantCFlag){
            language = Constant.C;
        }else if(!constantCPPFlag){
            language = Constant.CXX;
        }

        // 写完所有文件开始用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("projectName:{}, detailId:{} 开始调用sonar分析,语言:{}", projectName, taskInfoDetail.getId(), language);
        sonarService.sonar(language, param);

        // 提交一个查结果的任务
        SonarQueryResultRunnable queryResultRunnable = new SonarQueryResultRunnable(projectName, taskInfoDetail.getId(), dbOperateService);
        LOGGER.info("projectName:{}, detailId:{} 提交了查询结果的任务", projectName, taskInfoDetail.getId());
        queryResultPool.execute(queryResultRunnable);
    }


    public DbOperateService getDbOperateService() {
        return dbOperateService;
    }

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

    public SonarService getSonarService() {
        return sonarService;
    }

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