package _VisualDVM.Passes.All;
import Common.Utils.Utils_;
import Common.Visual.Controls.PassMenuItem;
import Common.Visual.UI;
import _VisualDVM.Current;
import _VisualDVM.Global;
import _VisualDVM.Passes.PassCode;
import _VisualDVM.Passes.Server.ComponentsServerPass;
import _VisualDVM.ProjectData.Files.DBProjectFile;
import _VisualDVM.ProjectData.Project.db_project_info;
import _VisualDVM.Repository.Server.ServerCode;
import _VisualDVM.Utils;
import org.apache.commons.io.FileUtils;

import javax.swing.*;
import java.io.File;
import java.nio.file.Paths;
import java.util.Date;
import java.util.Vector;
public class DVMConvertProject extends ComponentsServerPass<db_project_info> {
    File workspace = null;
    File archive = null;
    Vector<DBProjectFile> programsToConvert = null;
    Vector<String> programsNames = null;
    String output = null;
    File versionArchive = null;
    File version = null;
    String badFiles = "";
    @Override
    protected boolean canStart(Object... args) throws Exception {
        programsToConvert = null;
        programsNames = null;
        output = "";
        workspace = null;
        archive = null;
        versionArchive = null;
        version = null;
        badFiles = "";
        //--
        if (Global.mainModule.Check(Log, Current.Project)) {
            target = Global.mainModule.getProject();
            programsToConvert = target.getPrograms().get(target.languageName);
            programsNames = new Vector<>();
            if (programsToConvert.size() > 100) {
                Log.Writeln_("Количество активных файлов кода на языке " + target.languageName + " в проекте превышает 100.");
                return false;
            }
            for (DBProjectFile program : programsToConvert) {
                if (Utils_.getFileSizeMegaBytes(program.file) > 1) {
                    Log.Writeln_("Размер файла кода " + Utils_.Brackets(program.name) + " превышает 1 Мб.");
                    return false;
                } else programsNames.add(Utils_.toU(program.name));
            }
            workspace = Utils.getTempFileName("convertation");
            FileUtils.forceMkdir(workspace);
            File cleanCopy = Paths.get(workspace.getAbsolutePath(), target.name).toFile();
            FileUtils.forceMkdir(cleanCopy);
            archive = Paths.get(workspace.getAbsolutePath(), target.name + ".zip").toFile();
            target.Clone(cleanCopy, false);
            if (!Global.mainModule.getPass(PassCode.ZipFolderPass).Do(cleanCopy.getAbsolutePath(), archive.getAbsolutePath())) {
                Log.Writeln_("Не удалось создать архив проекта!");
                return false;
            }
            ;
            if (Utils_.getFileSizeMegaBytes(archive) > 500) {
                Log.Writeln_("Размер архива проекта превышает 500 МБ");
                return false;
            }
            //--
            Vector<String> unit_args = new Vector<>();
            unit_args.add(target.name);
            unit_args.add(target.languageName.toString());
            unit_args.add(target.sapforProperties.DVMConvertationOptions);
            unit_args.addAll(programsNames);
            return SendRequest(ServerCode.DVMConvertProject, String.join("\n", unit_args), Utils_.fileToBytes(archive));
            //--
        }
        return false;
    }
    @Override
    protected void performPreparation() throws Exception {
        super.performPreparation();
        db_project_info.ResetNewVersions();
    }
    //-
    @Override
    public String getIconPath() {
        return "/icons/Transformations/" + getName() + ".png";
    }
    @Override
    public boolean hasStats() {
        return true;
    }
    @Override
    protected void body() throws Exception {
        output = request.server_response.arg;
        versionArchive = new File(workspace, target.name + "_result.zip");
        request.server_response.Unpack(versionArchive);
        File result = new File(workspace, "result");
        if (Global.mainModule.getPass(PassCode.UnzipFolderPass).Do(versionArchive.getAbsolutePath(), result.getAbsolutePath())) {
            if (target.last_modification == null) {
                target.last_modification = new db_project_info(target,
                        "m",
                        "копия от " + new Date(),
                        "");
                target.last_modification.CloneParent();
            }
            File resultProject = new File(result, target.name);
            String versionName = target.GenerateVersionName("v");
            version = new File(target.Home, versionName);
            FileUtils.moveDirectory(resultProject, version);
            if (!version.exists()) Log.Writeln_("Не удалось перенести результат");
        } else Log.Writeln_("Не удалось распаковать результат");
    }
    @Override
    protected void performFinish() throws Exception {
        super.performFinish();
        String[] data = output.split("\\|");
        if (data.length > 1) {
            badFiles = "Не удалось сконвертировать " + data[0].split("\n").length + " файлов:\n" + data[0];
            target.updateCompilationOut(data[1]);
        } else
            target.updateCompilationOut(output);
    }
    @Override
    protected void showFinish() throws Exception {
        Global.mainModule.getUI().getMainWindow().getProjectWindow().RefreshProjectTreeAndMessages();
        if (Global.mainModule.HasFile()) {
            Global.mainModule.getFile().form.ShowCompilationOutput();
            if (!output.isEmpty())
                Global.mainModule.getFile().form.FocusCompilationOut();
        }
        if (!badFiles.isEmpty())
            UI.Error(badFiles);
    }
    @Override
    protected void performDone() throws Exception {
        target.joinExistingVersion(version, getDescription());
        target.migrateFilesSettings(target.last_version, false, false);
    }
    @Override
    public JMenuItem createMenuItem() {
        if (menuItem == null)
            menuItem = new PassMenuItem(this);
        return menuItem;
    }
    @Override
    protected void FocusResult() {
        Global.mainModule.getUI().getMainWindow().getProjectWindow().FocusVersions();
    }
}
