package _VisualDVM.Passes.All;
import Common.Utils.Utils_;
import Common.Visual.UI;
import _VisualDVM.ComponentsServer.Component.Sapfor.Sapfor;
import _VisualDVM.ComponentsServer.Component.Sapfor.TransformationPermission;
import _VisualDVM.Global;
import _VisualDVM.Passes.PassCode;
import _VisualDVM.Passes.Sapfor.SapforAnalysis;
import _VisualDVM.ProjectData.Files.DBProjectFile;
import _VisualDVM.ProjectData.Files.FileState;
import _VisualDVM.ProjectData.Files.FilesOrderJson;
import _VisualDVM.ProjectData.Files.UI.Editor.SPFEditor;
import org.apache.commons.io.FileUtils;

import java.util.Vector;
public class SPF_ParseFilesWithOrder extends SapforAnalysis {
    public static boolean silent = false;
    public static boolean precompilation_done = false;
    int goodCount = 0;
    int badCount = 0;
    Vector<String> projLines = new Vector<>();
    @Override
    public String phase() {
        return "PARSE_FILES";
    }
    @Override
    protected PassCode necessary() {
        return null;
    }
    protected boolean checkActiveFiles() {
        int count = 0;
        for (DBProjectFile f : target.db.files.Data.values())
            if (f.isActiveProgram()) {
                count++;
            }
        if (count == 0) {
            Log.Writeln_("В проекте не найдено ни одного активного файла типа 'Программа'.");
            return false;
        } else return true;
    }
    @Override
    protected boolean canStart(Object... args) throws Exception {
        precompilation_done = false;
        boolean res = (
                silent ||
                        (!Global.mainModule.getProject().sapforProperties.Precompilation ||
                                (precompilation_done = Global.mainModule.getPass(PassCode.Precompilation).Do())))
                && super.canStart(args) && checkActiveFiles();
        return res;
    }
    @Override
    protected boolean isGoodCode() {
        return sapfor.getErrorCode() == 0;
    }
    @Override
    public boolean needsConfirmations() {
        return !silent;
    }
    @Override
    protected void unpackMessages() throws Exception {
        System.out.println("packed=" + sapfor.getOutputMessage());
        for (DBProjectFile f : target.db.files.Data.values())
            if (f.isActive()) f.state = FileState.OK;
        super.unpackMessages();
        projLines.clear();
        goodCount = 0;
        badCount = 0;
        for (DBProjectFile f : target.db.files.Data.values()) {
            if (f.isActive()) {
                System.out.println("file=" + f.name + ":" + f.state);
                switch (f.state) {
                    case OK:
                    case HasNotes:
                    case HasWarnings:
                        if (f.isActiveProgram())
                            projLines.add(Utils_.toU(f.getDepFile().getAbsolutePath()));
                        goodCount++;
                        break;
                    case HasErrors:
                        badCount++;
                        break;
                    default:
                        break;
                }
            }
        }
        FileUtils.writeLines(target.getProjFile(), projLines, false);
    }
    @Override
    protected boolean validate() {
        if (super.validate()) {
            if (badCount > 0) {
                Log.Writeln_("Найдено файлов с синтаксическими ошибками: " + badCount);
                return false;
            }
            if (goodCount == 0) {
                Log.Writeln_("Не найдено ни одного успешно проанализированного файла на языке проекта :" +
                        Utils_.DQuotes(target.languageName.getDescription()));
                return false;
            }
            return true;
        }
        return false;
    }
    @Override
    protected void unpack(String packed) throws Exception {
        FilesOrderJson filesOrderJson = Utils_.gson.fromJson(packed, FilesOrderJson.class);
        for (String fileName_ : filesOrderJson.allFiles)
            target.files_order.add(Utils_.toW(fileName_));
    }
    @Override
    protected void performPreparation() throws Exception {
        super.performPreparation(); //удаление интеррупта.
        //------------------------------------------------------------------------------------------>>> пакетный режим.
        if (!precompilation_done && UI.isActive()) {
            Global.mainModule.getPass(PassCode.Save).Do();
            target.CleanAnalyses();
        }
        //перезапуск сапфора.------
        sapfor.Restart(); // тут же идет и сброс актуальности всех анализов.
        sapfor.cd(target.Home);
        sapfor.GetIntrinsics();
        //--------------------------
        projLines.clear();
        Sapfor.transformationPermission = TransformationPermission.None;
        target.CreateParserOptionsDirs();
        //---------------------------
        for (DBProjectFile f : target.db.files.Data.values()) {
            if (f.isActiveProgram()) {
                projLines.add(Utils_.toU(f.file.getAbsolutePath()));
                f.CreateParserOptions();
            }
        }
        FileUtils.writeLines(target.getProjFile(), projLines, false);
        /*
        if (projLines.isEmpty())
            throw new PassException("Язык проекта "+
                    Utils.DQuotes(target.languageName.getDescription())+",\n" +
                    "но не найдено ни одного файла на этом языке");
         */
    }
    @Override
    protected void showPreparation() throws Exception {
        if (!precompilation_done) {
            Global.mainModule.getUI().getMainWindow().getProjectWindow().ShowNoAnalyses();
            if (Global.mainModule.HasFile()) {
                Global.mainModule.getFile().form.ShowNoMessages();
                Global.mainModule.getFile().form.ShowNoAnalyses();
            }
        }
    }
    @Override
    protected void performDone() throws Exception {
        super.performDone();
        sapfor.Restart(); //рестарт скидывает все анализы в том числе парс и текущую папку.
        sapfor.cd(target.Home);
        Global.mainModule.getPass(PassCode.RestoreSavedArrays).Do();
        setDone();
        Sapfor.transformationPermission = TransformationPermission.All;
        SPFEditor.enable_text_changed = true;
    }
    @Override
    protected void performFinish() throws Exception {
        target.sapforProperties.PARSE_FOR_INLINE = false;
        target.sapforProperties.Update();
        super.performFinish();
    }
    @Override
    protected void showFinish() throws Exception {
        super.showFinish();
        Global.mainModule.getUI().getMainWindow().getProjectWindow().ShowAllAnalyses();
        if (Global.mainModule.HasFile())
            Global.mainModule.getFile().form.ShowAllAnalyses();
    }
    @Override
    protected void showFail() throws Exception {
        super.showFail();
    }
    @Override
    protected void FocusResult() {
        super.FocusResult();
        Global.mainModule.getUI().getMainWindow().getProjectWindow().FocusFile();
    }
    @Override
    protected void performFail() throws Exception {
        super.performFail();
        Utils_.forceDeleteWithCheck(target.getProjFile());
    }
}
