package Visual_DVM_2021.Passes.All;
import Common.Utils.Utils_;
import Common.Visual.UI_;
import _VisualDVM.Current;
import _VisualDVM.GlobalData.GlobalDatabase;
import _VisualDVM.Global;
import _VisualDVM.Visual.UI;
import _VisualDVM.Utils;
import _VisualDVM.GlobalData.Settings.SettingName;
import _VisualDVM.ProjectData.Files.DBProjectFile;
import _VisualDVM.ProjectData.Files.FileState;
import _VisualDVM.Repository.Component.Sapfor.TransformationPermission;
import Visual_DVM_2021.Passes.PassCode;
import Visual_DVM_2021.Passes.SapforAnalysis;
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.getDb().settings.get(SettingName.Precompilation).toBoolean() ||
                                (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 {
        target.updateLog(sapfor.getOutput());
        projLines.clear();
        goodCount = 0;
        badCount = 0;
        for (DBProjectFile f : target.db.files.Data.values())
            if (f.isActive()) f.state = FileState.OK;
        for (DBProjectFile f : target.db.files.Data.values()) {
            f.ReadParseMessages();
            f.father.db.Update(f);
            if (f.isActive()) {
                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 {
        for (String fileName_ : packed.split("\\|"))
            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();
        Global.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) {
            UI.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();
        /*
        //особенность парса. журнал появляется только сейчас.
        if (!sapfor.getOutput().isEmpty()) {
           target.updateLog(sapfor.getOutput());
        }
         */
        Global.transformationPermission = TransformationPermission.All;
        Global.enable_text_changed = true;
    }
    /*
    @Override
    protected void showDone() throws Exception {
        super.showDone();
        UI.getNewMainWindow().getProjectWindow().ShowProjectSapforLog();
    }
     */
    @Override
    protected void performFinish() throws Exception {
        Global.changeSetting(SettingName.PARSE_FOR_INLINE, "0");
        // Pass_2021.passes.get(PassCode_2021.UpdateSetting).Do(SettingName.PARSE_FOR_INLINE, "0");
        super.performFinish();
    }
    @Override
    protected void showFinish() throws Exception {
        super.showFinish();
        UI.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();
        UI.getMainWindow().getProjectWindow().FocusFile();
    }
    @Override
    protected void performFail() throws Exception {
        super.performFail();
        Utils.forceDeleteWithCheck(target.getProjFile());
    }
}
