package _VisualDVM.GlobalData.Tasks.RunTask;
import Common.CommonConstants;
import Common.Utils.StringTemplate;
import Common.Utils.Utils_;
import _VisualDVM.Global;
import _VisualDVM.GlobalData.Compiler.CompilerType;
import _VisualDVM.GlobalData.RunConfiguration.RunConfiguration;
import _VisualDVM.GlobalData.Tasks.CompilationTask.CompilationTask;
import _VisualDVM.GlobalData.Tasks.Task;
import _VisualDVM.GlobalData.Tasks.TaskState;
import _VisualDVM.ProjectData.Project.db_project_info;
import _VisualDVM.Utils;
import com.sun.org.glassfish.gmbal.Description;
import org.apache.commons.io.FileUtils;

import java.io.File;
import java.nio.file.Paths;
import java.util.List;
public class RunTask extends Task {
    public int compilation_task_id = CommonConstants.Nan; //нужна для бинарника
    public int run_configuration_id = CommonConstants.Nan;
    @Description("DEFAULT ''")
    public String last_sts_name = "";
    @Description("DEFAULT 0")
    public double CleanTime;
    @Description("IGNORE")
    public boolean hasDvmSts = false;
    @Description("IGNORE")
    public boolean hasGCOV = false;
    //-------------------------------------
    @Description("DEFAULT ''")
    public String matrix = "";
    //-------------------------------------
    @Override
    public void DropResults() throws Exception {
        super.DropResults();
        Utils_.forceDeleteWithCheck(getLocalStsFile());
        CleanTime = 0;
        Global.mainModule.getDb().Update(this);
    }
    @Override
    public File getHome() {
        return Global.RunTasksDirectory;
    }
    @Override
    public String getFullCommand() {
        return getRunConfiguration().getLaunchScriptText(getCompilationTask().binary_name, matrix);
    }
    //---------------------------------------
    public RunConfiguration getRunConfiguration() {
        return (Global.mainModule.getDb()).runConfigurations.Data.get(run_configuration_id);
    }
    public CompilationTask getCompilationTask() {
        return (Global.mainModule.getDb()).compilationTasks.Data.get(compilation_task_id);
    }
    public void UpdateLastStsName(String file_name) {
        if (!last_sts_name.equals(file_name)) {
            last_sts_name = file_name;
            try {
                Global.mainModule.getDb().Update(this);
            } catch (Exception ex) {
                Utils_.MainLog.PrintException(ex);
            }
        }
    }
    public File getLocalStsFile() {
        return Paths.get(getLocalWorkspace().getAbsolutePath(), last_sts_name).toFile();
    }
    public File getLocalStsTextFile() {
        return Paths.get(getLocalWorkspace().getAbsolutePath(), "statistic.txt").toFile();
    }
    public String getLocalStsText() {
        return getTextResult(getLocalStsTextFile());
    }
    public void parseCleanTime() {
        StringTemplate template = new StringTemplate("Time in seconds =", "");
        String p = template.check_and_get_param(Utils.ReadAllText(getOutputFile()));
        try {
            if (p != null) CleanTime = Double.parseDouble(p);
        } catch (Exception ex) {
            Utils_.MainLog.PrintException(ex);
        }
    }
    @Override
    public void AnalyzeOutFile(db_project_info project) throws Exception {
        List<String> lines = FileUtils.readLines(getOutputFile());
        if (lines.stream().anyMatch(Utils::isCrushedLine)
        ) {
            state = TaskState.Crushed;
            return;
        }
        //->>
        //тест на корректность.
        if (!lines.isEmpty() && lines.get(0).toUpperCase().contains("START OF ")) {
            int complete = 0;
            int errors = 0;
            for (int i = 1; i < lines.size(); ++i) {
                String line_ = lines.get(i).toUpperCase();
                if (line_.endsWith("COMPLETE")) {
                    complete++;
                } else if (line_.endsWith("ERROR")) {
                    errors++;
                } else if (line_.contains("END OF")) {
                    if (errors > 0) state = TaskState.DoneWithErrors;
                    else if (complete > 0) state = TaskState.Done;
                    return;
                }
            }
        }
        //тест на производительность.
        StringTemplate stringTemplate = new StringTemplate("Verification =", "");
        for (String line : lines) {
            String param = stringTemplate.check_and_get_param(line);
            if (param != null) {
                switch (param) {
                    case "SUCCESSFUL":
                        state = TaskState.Done;
                        return;
                    case "UNSUCCESSFUL":
                        state = TaskState.DoneWithErrors;
                        return;
                    default:
                        break;
                }
            }
        }
    }
    @Override
    public void AnalyzeErrorsFile(db_project_info project) throws Exception {
        List<String> lines = FileUtils.readLines(getErrorsFile());
        if (lines.stream().anyMatch(Utils::isCrushedLine))
            state = TaskState.Crushed;
    }
    @Override
    public void Reset() {
        super.Reset();
        CleanTime = 0.0;
        hasDvmSts = false;
        hasGCOV = false;
    }
    public boolean hasDVMPar() {
        RunConfiguration config = getRunConfiguration();
        return
                config.compiler_id != CommonConstants.Nan &&
                        config.getCompiler().type.equals(CompilerType.dvm) &&
                        !config.getParList().isEmpty()
                ;
    }
}
