package _VisualDVM.GlobalData.Tasks.Supervisor.Remote;
import Common.CommonConstants;
import Common.Passes.PassException;
import Common.Utils.Utils_;
import _VisualDVM.Constants;
import _VisualDVM.Global;
import _VisualDVM.GlobalData.RemoteFile.RemoteFile;
import _VisualDVM.GlobalData.Tasks.Supervisor.TaskSupervisor;
import _VisualDVM.GlobalData.Tasks.Task;
import _VisualDVM.GlobalData.Tasks.TaskState;
import _VisualDVM.Passes.SSH.ConnectionPass;
public abstract class RemoteTaskSupervisor<T extends Task> extends TaskSupervisor<T, ConnectionPass> {
    protected RemoteFile getRemoteProjectsPath() {
        return new RemoteFile(pass.user.getRemoteProjectsPath(), true);
    }
    protected RemoteFile getRemoteProject() {
        return new RemoteFile(getRemoteProjectsPath().full_name, project.getUniqKey(), true);
    }
    protected RemoteFile getBinary() {
        return new RemoteFile(getRemoteProject().full_name, "0");
    }
    protected RemoteFile getPID() {
        return new RemoteFile(getRemoteProject().full_name, "PID");
    }
    protected RemoteFile getRemoteTime() {
        return new RemoteFile(getRemoteProject().full_name, Constants.time_file);
    }
    protected RemoteFile getRemoteOutput() {
        return new RemoteFile(getRemoteProject().full_name, Constants.out_file);
    }
    protected RemoteFile getRemoteErrors() {
        return new RemoteFile(getRemoteProject().full_name, Constants.err_file);
    }
    public RemoteFile getDONE_file() {
        return new RemoteFile(getRemoteProject().full_name, CommonConstants.DONE);
    }
    public RemoteFile getTIMEOUT_file() {
        return new RemoteFile(getRemoteProject().full_name, CommonConstants.TIMEOUT);
    }
    @Override
    protected void PrepareWorkspace() throws Exception {
        super.PrepareWorkspace(); //локальная подготовка
        pass.user.connection.tryRM(getDONE_file());
        pass.user.connection.tryRM(getPID());
        pass.user.connection.tryRM(getTIMEOUT_file());
        pass.user.connection.tryRM(getRemoteOutput());
        pass.user.connection.tryRM(getRemoteErrors());
        pass.user.connection.tryRM(getRemoteTime());
    }
    @Override
    protected void CheckTask() throws Exception {
        RemoteFile DONE = new RemoteFile(getRemoteProject(), CommonConstants.DONE);
        RemoteFile TIMEOUT = new RemoteFile(getRemoteProject(), CommonConstants.TIMEOUT);
        if (pass.user.connection.Exists(DONE))
            task.state = TaskState.Finished;
        else if (pass.user.connection.Exists(TIMEOUT))
            task.state = TaskState.AbortedByTimeout;
    }
    @Override
    protected void AchieveResults() throws Exception {
        pass.user.connection.tryGetSingleFileWithMaxSize(getRemoteOutput(), task.getOutputFile(), 10240);
        pass.user.connection.tryGetSingleFileWithMaxSize(getRemoteErrors(), task.getErrorsFile(), 10240);
    }
    @Override
    protected void AbortTask() throws Exception {
        //1 прочитать пид
        if (task.PID.isEmpty()) {
            RemoteFile PID = getPID();
            if (pass.user.connection.Exists(PID)) {
                task.PID = pass.user.connection.readFromFile(PID).replace("\n", "").replace("\r", "");
                Global.mainModule.getDb().Update(task);
            } else {
                throw new PassException("файл PID не найден");
            }
        }
        pass.user.connection.Command("kill -2 " + task.PID);
    }
    @Override
    protected void CalculatePerformanceTime() throws Exception {
        if (pass.user.connection.tryGetSingleFileWithMaxSize(getRemoteTime(), task.getTimeFile(), 0))
            task.RefreshTime();
    }
    public String getStarter() {
        return String.join("/", pass.user.workspace, "modules", "starter");
    }
    public String getLauncher() {
        return String.join("/", pass.user.workspace, "modules", "launcher");
    }
    protected String getStartCommand() {
        String res =
                String.join(" ",
                        Utils_.DQuotes(getStarter()),
                        Utils_.DQuotes(getLauncher()),
                        String.valueOf(task.maxtime),
                        Utils_.DQuotes(getCoupDeGrace()),
                        task.getFullCommand()
                );
        return res;
    }
}
