package _VisualDVM.ComponentsServer.Component;
import Common.Passes.PassException;
import Common.Utils.Utils_;
import Common.Visual.UI;
import _VisualDVM.Global;
import _VisualDVM.Utils;

import java.io.BufferedReader;
import java.io.File;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
import java.nio.file.Paths;
import java.util.Date;
public class Visualizer_2 extends OSDComponent {
    public String PID = "";
    //</editor-fold>
    //-
    //<editor-fold desc="функционал">
    int port;
    Socket client = null;
    PrintWriter out = null;
    BufferedReader in = null;
    String request = "";
    String response = "";
    public Visualizer_2(int port_in) {
        port = port_in;
    }
    public static void UnpackVersionInfo(Component component, String packed) {

        String[] data = packed.split("\\|");
        //лишний пробел.
        String text = data[0].substring(0, data[0].length() - 1);
        component.date_text = data[1] + data[2] + data[3];
        component.version = Long.parseLong(text);

      //  component.version = 6666;
      //  component.date_text = new Date().toString();
    }
    //<editor-fold desc="компонент">
    @Override
    public ComponentType getComponentType() {
        return ComponentType.Visualizer_2;
    }
    @Override
    public String getHome() {
        return Utils_.getHomePath();
    }
    @Override
    public void GetVersionInfo() {
        try {
            Command("get_version: ");
            UnpackVersionInfo(this, response);
        } catch (Exception e) {
            Utils_.MainLog.PrintException(e);
        }
    }
    public void refreshPid() {
        try {
            //    UI.Info("Getting Server PID...");
            Command("get_pid: ");
            PID = response;
            //   UI.Info("SERVER PID = "+Utils.Brackets(PID));
        } catch (Exception e) {
            Utils_.MainLog.PrintException(e);
        }
    }
    @Override
    public void Update() throws Exception {
        super.Update();
        SendRequest("update_server: ");
        ReplaceOldFile();
        UI.Info("Сервер успешно обновлен.\n" +
                "Визуализатор завершает работу.\n" +
                "Для продолжения перезапустите визуализатор вручную.");
        System.exit(0);
    }
    @Override
    public String getAssemblyCommand() {
        File src_home = Paths.get(Global.RepoDirectory.getAbsolutePath(), "SAPFOR/src/Server").toFile();
        return "cd " + Utils_.DQuotes(src_home) +
                "\n" +
                "g++ -O3 -std=c++17 checkUniq.cpp server.cpp -o Visualizer_2 -lpthread -lstdc++fs\n";
    }
    @Override
    public File getAssemblyFile() {
        return Paths.get(
                Global.RepoDirectory.getAbsolutePath(),
                "SAPFOR/src/Server/Visualizer_2").toFile();
    }
    public void Connect() throws Exception {
        ClearLog();
        Print("соединение с Visualiser_2...");
        client = Utils.createClientSocket(
                InetAddress.getLoopbackAddress(),
                port, 0
        );
        in = new BufferedReader(new InputStreamReader(client.getInputStream())); //то что нам приходит от сервера
        out = new PrintWriter(client.getOutputStream(), true); //то что мы пишем серверу.
    }
    public void Interrupt() {
        Utils.Kill(PID, false);
    }
    public void Shutdown() throws Exception {
        Print("завершение сеанса с Visualiser_2...");
        SendRequest("close: ");
        if (client != null)
            client.close();
        if (in != null)
            in.close();
        if (out != null)
            out.close();
    }
    //запрос.
    public void SendRequest(String request_in) throws Exception {
        Print("->" + request_in);
        out.flush();
        System.gc();
        out.println(request = request_in);
    }
    //запрос-ответ. анализируются только общие ошибочные случаи.
    public String Command(String request_in) throws Exception {
        SendRequest(request_in);
        response = in.readLine();
        switch (response) {
            case "NOT_FOUND":
            case "WRONG":
            case "SEG_FAULT":
                throw new PassException("Команда серверу SAPFOR вернула " + Utils_.Brackets(response));
            default:
                break;
        }
        Print("<-" + response);
        out.flush();
        System.gc();
        return response;
    }
    //</editor-fold>
}
