package Visual_DVM_2021.Passes.All;
import Common.Current;
import Common.Utils.Utils;
import GlobalData.RemoteFile.RemoteFile;
import Visual_DVM_2021.Passes.PassException;
import Visual_DVM_2021.Passes.SSH.ConnectionPass_2023;
import javafx.util.Pair;

import java.io.File;
import java.util.Vector;
public class RemoteInitialiseUser extends ConnectionPass_2023<RemoteFile> {
    RemoteFile modulesDirectory;
    @Override
    protected boolean needsAnimation() {
        return true;
    }
    @Override
    protected boolean canStart(Object... args) {
        return Current.Check(Log, Current.User);
    }
    @Override
    protected void Connect() throws Exception {
        machine = Current.getMachine();
        user = Current.getUser();
        super.Connect();
    }
    void put_resource(String res_name, RemoteFile dst_directory) throws Exception {
        user.connection.putSingleFile(Utils.CreateTempResourceFile(res_name), new RemoteFile(dst_directory, res_name));
    }
    void compileModule(String module_name, String flags) throws Exception{
        String command = "g++ " + flags+" "+ Utils.DQuotes(module_name + ".cpp") + " -o "+ Utils.DQuotes(module_name);
        ShowMessage2(command);
        user.connection.performScript(modulesDirectory, command);
        RemoteFile binary = new RemoteFile(modulesDirectory, module_name);
        if (!user.connection.Exists(binary)){
            throw new PassException("Не удалось собрать модуль "+Utils.Brackets(module_name));
        }else {
            user.connection.sftpChannel.chmod(0777, binary.full_name);
        }
    }
    String getPlannerFlags() throws Exception{
        String res = "";
        String command = "g++ -v --help 2> /dev/null | sed -n '/^ *-std=\\([^<][^ ]\\+\\).*/ {s//\\1/p}' | grep c++";
        System.out.println(command);
        Pair<RemoteFile, RemoteFile> oe = user.connection.performScript(modulesDirectory, command);
        RemoteFile outFile = oe.getKey();
        String out = user.connection.readFromFile(outFile);
        String [] data = out.split("\n");
        for (String version: data){
            System.out.println(Utils.Brackets(version));
            if (version.equals("c++17")){
                res = "-std=c++17";
                break;
            }else if (version.equals("c++11")){
                res="-std=c++11";
                break;
            }
        }
        System.out.println(Utils.Brackets(res));
        if (res.isEmpty())
            throw new PassException("На целевой машине отсутствуют с++17 и с++11!");
        return res;
    }
    @Override
    protected void ServerAction() throws Exception {
        String workspace_name = Utils.getDateName("visual_sapfor_workspace");
        ShowMessage1("Создание рабочего пространства...");
        target = new RemoteFile(user.connection.sftpChannel.getHome(), workspace_name);
        user.connection.sftpChannel.mkdir(target.full_name);
        Vector<RemoteFile> subdirectories = new Vector<>();
        subdirectories.add(new RemoteFile(target, "projects"));
        subdirectories.add(modulesDirectory = new RemoteFile(target, "modules"));
        subdirectories.add(new RemoteFile(target, "tests"));
        //-------------------------------------
        for (RemoteFile remoteFile : subdirectories)
            user.connection.sftpChannel.mkdir(remoteFile.full_name);
        //----------------------------------
        String[] resourses_names = new String[]{
                //--
                "Process_r.h",
                "starter.cpp",
                "launcher.cpp",
                //--
                "Array.h",
                "CompilationSupervisor.h",
                "CompilationTask.h",
                "File.h",
                "Global.h",
                "planner.cpp",
                "RunSupervisor.h",
                "RunTask.h",
                "String.h",
                "Supervisor.h",
                "Task.h",
                "Text.h",
                "Utils.h"
        };
        ShowMessage1("Закачка кода модулей...");
        for (String resource_name : resourses_names) {
            ShowMessage2(resource_name);
            File src = Utils.CreateTempResourceFile(resource_name);
            RemoteFile dst = new RemoteFile(modulesDirectory, resource_name);
            user.connection.putSingleFile(src, dst);
        }
        //-------------------------------------
        ShowMessage1("Сборка модулей...");
        compileModule("launcher","");
        compileModule("starter","");
        compileModule("planner", getPlannerFlags());
        //--------------------------------------
        RemoteFile info = new RemoteFile(target, Current.getAccount().email);
        user.connection.writeToFile("", info);
    }
}
