package _VisualDVM.ComponentsServer.Component.Sapfor;
import Common.CommonConstants;
import Common.Passes.PassException;
import Common.Utils.Pair;
import Common.Utils.Utils_;
import Common.Visual.UI;
import _VisualDVM.ComponentsServer.Component.Json.VersionInfo_json;
import _VisualDVM.ComponentsServer.Component.OSDComponent;
import _VisualDVM.Constants;
import _VisualDVM.Global;
import _VisualDVM.Passes.PassCode;
import _VisualDVM.Passes.Sapfor.SapforAnalysis;
import _VisualDVM.ProjectData.Files.DBProjectFile;
import _VisualDVM.ProjectData.Files.UI.Editor.SPFEditor;
import _VisualDVM.ProjectData.Project.db_project_info;
import _VisualDVM.ProjectData.SapforData.ModifiedFile_json;
import _VisualDVM.ProjectData.SapforData.SapforResult_json;
import _VisualDVM.TestingSystem.Common.Test.Test;
import _VisualDVM.Utils;
import org.apache.commons.io.FileUtils;

import java.io.File;
import java.nio.charset.Charset;
import java.util.*;
import java.util.concurrent.TimeUnit;
public abstract class Sapfor extends OSDComponent {
    public static final int empty_code = -100;
    public static final int canceled_code = -99;
    public static final int invalid_proj_code = -2;
    public static File temp_copy = null;
    //---
    public static TransformationPermission transformationPermission = TransformationPermission.None;
    public Vector<String> Intrinsics = new Vector<>();
    public LinkedHashMap<String, String> ModifiedFiles = new LinkedHashMap<>();
    public LinkedHashMap<String, String> OldFiles = new LinkedHashMap<>();
    String PID = "";
    private int errorCode;
    private String result;
    private String output;
    private String outputMessage;
    private String predictorStats;
    //-
    public static String pack(String... params) {
        StringBuilder res = new StringBuilder();
        for (String param : params)
            res.append(param.length()).append(" ").append(param);
        return res.toString();
    }
    public static PassCode[] getAnalysesCodes() {
        return new PassCode[]{
                PassCode.SPF_ParseFilesWithOrder,
                PassCode.SPF_GetFileLineInfo,
                PassCode.SPF_GetArrayDistributionOnlyRegions,
                PassCode.SPF_GetIncludeDependencies,
                PassCode.SPF_GetGraphLoops,
                PassCode.SPF_GetGraphFunctions,
                PassCode.SPF_GetAllDeclaratedArrays,
                PassCode.SPF_GetArrayDistributionOnlyAnalysis,
                PassCode.SPF_GetArrayDistribution
        };
    }
    public static PassCode[] getLoopsTransformationsCodes() {
        return new PassCode[]{
                PassCode.SPF_LoopEndDoConverterPass,
                PassCode.SPF_LoopFission,
                PassCode.SPF_LoopUnion,
                PassCode.SPF_LoopUnrolling
        };
    }
    public static PassCode[] getPrivatesTransformationsCodes() {
        return new PassCode[]{
                PassCode.SPF_PrivateShrinking,
                PassCode.SPF_PrivateExpansion,
                PassCode.SPF_PrivateRemoving,
                PassCode.SPF_InsertPrivateFromGUI,
                PassCode.SPF_InsertPrivateArrayDirectives
        };
    }
    public static PassCode[] getProceduresTransformationsCodes() {
        return new PassCode[]{
                PassCode.SPF_InlineProcedures,
                PassCode.SPF_InlineProceduresH,
                PassCode.SPF_DuplicateFunctionChains,
                PassCode.SPF_RemoveUnusedFunctions
        };
    }
    public static PassCode[] getDVMTransformationsCodes() {
        return new PassCode[]{
                PassCode.SPF_RemoveDvmDirectivesToComments,
                PassCode.SPF_RemoveDvmDirectives,
                PassCode.SPF_RemoveOmpDirectives,
                PassCode.SPF_RemoveSpfDirectives
        };
    }
    public static PassCode[] getIntervalsTransformationsCodes() {
        return new PassCode[]{
                PassCode.SPF_CreateIntervalsTree,
                PassCode.SPF_RemoveDvmIntervals
        };
    }
    public static PassCode[] getRegionsTransformationsCodes() {
        return new PassCode[]{
                PassCode.SPF_ResolveParallelRegionConflicts,
                PassCode.SPF_InsertDvmhRegions,
                PassCode.SPF_RemoveDistArraysFromIO
        };
    }
    public static PassCode[] getPreparationTransformationsCodes() {
        return new PassCode[]{
                PassCode.SPF_CorrectCodeStylePass,
                PassCode.SPF_MoveOperators,
                PassCode.SPF_RenameIncludes,
                PassCode.SPF_InsertIncludesPass,
                PassCode.SPF_ConvertStructures,
                PassCode.SPF_CreateCheckpoints,
                PassCode.SPF_InitDeclsWithZero,
                PassCode.SPF_ExpressionSubstitution,
                PassCode.EraseBadSymbols,
                PassCode.SPF_RemoveComments,
                PassCode.SPF_RemoveDeadCode,
                PassCode.CombineFiles,
                PassCode.CopyProject,
                PassCode.PrepareForModulesAssembly,
                PassCode.DVMConvertProject,
                PassCode.SPF_ResolveCommonBlockConflicts,
                PassCode.SPF_InsertImplicitNone
        };
    }
    //----------
    public static Vector<PassCode> getScenariosCodes() {
        Vector<PassCode> res = new Vector<>();
        res.add(PassCode.SPF_InitDeclsWithZero);//+
        res.add(PassCode.SPF_ConvertStructures);//+
        res.add(PassCode.SPF_ExpressionSubstitution);//+
        //--
        res.add(PassCode.SPF_CreateCheckpoints); //+
        res.add(PassCode.SPF_CreateIntervalsTree);//+
        res.add(PassCode.SPF_RemoveDvmIntervals);//+
        //--
        res.add(PassCode.SPF_RemoveDvmDirectives); //+
        res.add(PassCode.SPF_RemoveDvmDirectivesToComments); //+
        res.add(PassCode.SPF_RemoveOmpDirectives);//+
        res.add(PassCode.SPF_RemoveComments);//+
        res.add(PassCode.SPF_RemoveDeadCode);//+
        res.add(PassCode.SPF_RenameIncludes);
        res.add(PassCode.SPF_InsertIncludesPass);//+
        //--
        res.add(PassCode.SPF_LoopEndDoConverterPass); //+
        res.add(PassCode.SPF_LoopUnion);//+
        res.add(PassCode.SPF_LoopFission);//+
        //--
        res.add(PassCode.SPF_PrivateShrinking);//+
        res.add(PassCode.SPF_PrivateExpansion);//+
        res.add(PassCode.SPF_PrivateRemoving);//+
        res.add(PassCode.SPF_InsertPrivateArrayDirectives);
        //--
        res.add(PassCode.SPF_RemoveUnusedFunctions);//+
        res.add(PassCode.SPF_DuplicateFunctionChains);//+
        //--
        res.add(PassCode.SPF_ResolveParallelRegionConflicts);//+
        res.add(PassCode.SPF_RemoveDistArraysFromIO);
        res.add(PassCode.SPF_ResolveCommonBlockConflicts);//+
        //-
        res.add(PassCode.SPF_InsertDvmhRegions);//+
        res.add(PassCode.SPF_SharedMemoryParallelization);//+
        res.add(PassCode.SPF_InsertImplicitNone);//+
        res.add(PassCode.SPF_MoveOperators);
        res.add(PassCode.CreateParallelVariants); //?
        return res;
    }
    public static boolean checkLines(Vector<String> lines) {
        for (String line : lines) {
            if (line.toLowerCase().contains("internal error")) {
                return false;
            }
            if (line.toLowerCase().contains("exception")) {
                return false;
            }
            if (line.contains("[ERROR]")) {
                return false;
            }
            if (line.toLowerCase().contains("segmentation fault")) {
                return false;
            }
            /*
            if (line.toLowerCase().contains("error in unparse")) {
                return false;
            }
             */
        }
        return true;
    }
    //--
    public static boolean performScript(String name, //имя скрипта
                                        File sapfor_drv, //путь к сапфору
                                        File workspace, //проект
                                        String command, //проход
                                        String flags,   //флаги
                                        String outName,
                                        String errName,
                                        Vector<String> resultLines
    ) throws Exception {
        Process process = null;
        int exit_code = CommonConstants.Nan;
        //---
        File data_workspace = new File(workspace, Constants.data);
        Utils_.CheckDirectory(data_workspace);
        File outputFile = new File(data_workspace, outName);
        File errorsFile = new File(data_workspace, errName);
       // File logFile = new File(data_workspace, "log.txt");
        Utils_.forceDeleteWithCheck(outputFile);
        Utils_.forceDeleteWithCheck(errorsFile);
       // Utils_.forceDeleteWithCheck(logFile);
        //---
        File file = new File(data_workspace, name + (Utils_.isWindows() ? ".bat" : ".sh"));
        FileUtils.write(file,
                Utils_.DQuotes(sapfor_drv)
                        + (flags.isEmpty() ? "" : (" " + flags))
                        + " -noLogo"
                        + " " + command +
                        " 1>" +
                        Utils_.DQuotes(outputFile.getAbsolutePath()) +
                        " 2>" +
                        Utils_.DQuotes(errorsFile.getAbsolutePath()),
                Charset.defaultCharset());
        if (!file.setExecutable(true))
            throw new Exception("Не удалось сделать файл скрипта " + name + " исполняемым!");
        //-- Windows
        //запустить процесс
        boolean process_started = false;
        do {
            try {
                ProcessBuilder procBuilder = new ProcessBuilder(file.getAbsolutePath());
                procBuilder.directory(workspace);
                process = procBuilder.start();
                process_started = true;
            } catch (Exception ex) {
                Utils_.MainLog.PrintException(ex);
                Utils_.sleep(1000);
            }
        }
        while (!process_started);
        //--
        for (int i=0; i<40; ++i){
            if (process.waitFor(1, TimeUnit.SECONDS)){
                //дождались. все хорошо.
                exit_code=0;
               // FileUtils.writeStringToFile(logFile,sapfor_drv.getName()+" done for "+i+" seconds");
                break;
            }
        }
        if (exit_code!=0){
           // FileUtils.writeStringToFile(logFile,sapfor_drv.getName()+" timeout");
            //-
            Process killer = Runtime.getRuntime().exec("pkill -SIGKILL  -f "+sapfor_drv.getName());
            killer.waitFor();
            //-
        }
        process = null;
        //---
        Vector<String> outputLines = new Vector<>(FileUtils.readLines(outputFile));
        Vector<String> errorsLines = new Vector<>(FileUtils.readLines(errorsFile));
        if (resultLines != null) {
            resultLines.addAll(outputLines);
        }
        return (exit_code == 0) &&
                checkLines(outputLines) &&
                checkLines(errorsLines);
    }
    public static boolean performScript(String name, //имя скрипта
                                        File sapfor_drv, //путь к сапфору
                                        File workspace, //проект
                                        String command, //проход
                                        String flags,   //флаги
                                        String outName,
                                        String errName
    ) throws Exception {
        return performScript(name, sapfor_drv, workspace, command, flags, outName, errName, null);
    }
    public static boolean parse(File sapfor_drv, File workspace, String flags) throws Exception {
        return performScript(
                "parse",
                sapfor_drv,
                workspace,
                "-parse -spf *.f* *.F*", //         "-parse -spf *.f *.for *.fdv *.f90 *.f77",
                flags,
                Constants.parse_out_file,
                Constants.parse_err_file)
                && (new File(workspace, "dvm.proj")).exists();
    }
    public static boolean analysis(File sapfor_drv, File workspace, PassCode code, String flags, Vector<String> result_lines) throws Exception {
        return performScript("analysis",
                sapfor_drv,
                workspace,
                code.getTestingCommand(),
                flags,
                Constants.out_file,
                Constants.err_file,
                result_lines
        );
    }
    //--
    public static int readVersionFromCode(File versionFile) {
        int res = CommonConstants.Nan;
        if (versionFile.exists()) {
            try {
                List<String> data = FileUtils.readLines(versionFile);
                for (String s : data) {
                    if (s.startsWith("#define VERSION_SPF ")) {
                        String[] version_data = s.split("\"");
                        if (version_data.length > 0) {
                            String version_s = version_data[1];
                            //-
                            try {
                                res = Integer.parseInt(version_s);
                            } catch (Exception ex) {
                                ex.printStackTrace();
                            }
                        }
                    }
                }
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
        return res;
    }
    //--
    public static int getFileMaxDim_C(File file) {
        int fileMax = 0;
        final String prefix = "#pragma dvm array distribute";
        int n = 0;
        try {
            for (String line : FileUtils.readLines(file, Charset.defaultCharset())) {
                //  #pragma dvm array distribute[block][block], не важно
                String packedLine = Utils_.removeCharacters(Utils_.removeRedundantSpaces(line).toLowerCase(), "\n", "\r", "\t");
                if (packedLine.startsWith(prefix)) {
                    packedLine = packedLine.substring(prefix.length());
                    boolean bracketOpen = false;
                    int pragmaMax = 0;
                    String distr = "";
                    for (int i = packedLine.indexOf('['); i < packedLine.length(); ++i) {
                        char c = packedLine.charAt(i);
                        if (bracketOpen) {
                            if (c == ']') {
                                bracketOpen = false;
                                if (distr.equals("block"))
                                    pragmaMax++;
                                distr = "";
                            } else {
                                distr += c;
                            }
                        } else {
                            if (c == '[') {
                                bracketOpen = true;
                            } else {
                                break;
                            }
                        }
                    }
                    fileMax = Math.max(fileMax, pragmaMax);
                }
                ++n;
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return fileMax;
    }
    public static int getProjectMinMaxDim_C(db_project_info project) {
        int res = 0;
        for (DBProjectFile file : project.db.files.Data.values()) {
            if (file.isActiveProgram())
                res = Math.max(res, Sapfor.getFileMaxDim_C(file.file));
        }
        return res;
    }
    public static Pair<Integer, Integer> getProjectFolderMinMaxDim_F(File sapfor_drv, File projectPath) {
        String flags = "-noLogo";
        Pair<Integer, Integer> res = new Pair<>(0, 0);
        try {
            if (Sapfor.parse(sapfor_drv, projectPath, flags)
            ) {
                Vector<String> outputLines = new Vector<>();
                if (Sapfor.analysis(sapfor_drv, projectPath, PassCode.SPF_GetMaxMinBlockDistribution, flags, outputLines)) {
                    //---
                    for (String line : outputLines) {
                        String prefix = "GET_MIN_MAX_BLOCK_DIST: ";
                        if (line.startsWith(prefix)) {
                            String s = line.substring(prefix.length());
                            String[] data = s.split(" ");
                            res = new Pair<>(Math.max(Integer.parseInt(data[0]), 0), Math.max(Integer.parseInt(data[1]), 0));
                            break;
                        }
                    }
                }
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        } finally {
            try {
                Utils.deleteFilesByExtensions(projectPath,
                        "proj", "dep", "jar"
                );
                File visualiser_data = new File(projectPath, Constants.data);
                if (visualiser_data.exists())
                    FileUtils.forceDelete(visualiser_data);
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
        return res;
    }
    public static void getTestMinMaxDim_F(File sapfor_drv, Test test) {
        Pair<Integer, Integer> res = getProjectFolderMinMaxDim_F(sapfor_drv, test.getServerPath());
        test.min_dim = res.getKey();
        test.max_dim = res.getValue();
    }
    public static void getTestMinMaxDime_C(Test test) {
        int min_dim = 0;
        int max_dim = 0;
        for (File file : test.getServerFiles()) {
            max_dim = Math.max(max_dim, getFileMaxDim_C(file));
        }
        test.min_dim = min_dim;
        test.max_dim = max_dim;
    }
    public void refreshPid() {
        try {
            //  UI.Info("Calling SPF_GetCurrentPID...");
            RunAnalysis("SPF_GetCurrentPID", -1, "", "");
            PID = getResult();
            //  UI.Info("PID = " + Utils.Brackets(PID));
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
    //<editor-fold desc="компонент">
    @Override
    public void GetVersionInfo() {
        try {
            RunAnalysis("SPF_GetVersionAndBuildDate", -1, "", "");
            VersionInfo_json versionInfo_json = Utils_.gson.fromJson(getResult(),VersionInfo_json.class);
            version = versionInfo_json.version;
            date_text = versionInfo_json.build_date+" "+ versionInfo_json.build_time;
        } catch (Exception e) {
            Utils_.MainLog.PrintException(e);
            UI.Error("Не удалось получить версию компонента " + Utils_.DQuotes(getComponentType().getDescription()));
        }
    }
    public abstract String getUpdateCommand();
    public abstract String getRestartCommand();
    @Override
    public void Update() throws Exception {
        super.Update();
        Global.visualizer_2.Command(getUpdateCommand());
        GetVersionInfo();
        ResetAllAnalyses();
        refreshPid();
    }
    //</editor-fold>
    //--------
    //<editor-fold desc="функционал">
    public String readStatForAnalyzer(String src) throws Exception {
        RunAnalysis(
                "SPF_OpenDvmStatistic",
                -Global.messagesServer.getPort(),
                "",
                //  Global.packSapforSettings(),
                src);
        return result;
    }
    public void readStatToTxt(File src, File dst) throws Exception {
        RunAnalysis("SPF_StatisticAnalyzer",
                -1,
                "",
                Utils_.DQuotes(src.getAbsolutePath()) +
                        " "
                        + Utils_.DQuotes(dst.getAbsolutePath())
        );
    }
    public void Restart() throws Exception {
        ResetAllAnalyses();
        Global.visualizer_2.Command(getRestartCommand());
        refreshPid();
    }
    public void Interrupt() throws Exception {
        Utils.Kill(PID, true);
    }
    public void cd(File directory_in) throws Exception {
        if (RunAnalysis("SPF_ChangeDirectory", -1, directory_in.getAbsolutePath(), "") != 0)
            throw new PassException("Sapfor: Не удалось перейти в папку "
                    + Utils_.Brackets(directory_in.getAbsolutePath()) +
                    "\n" + "Код возврата: " + getErrorCode());
    }
    public String getResult() {
        return result;
    }
    public void setResult(String result) {
        this.result = result;
    }
    public int getErrorCode() {
        return errorCode;
    }
    public void setErrorCode(int errorCode) {
        this.errorCode = errorCode;
    }
    public String getOutput() {
        return output;
    }
    public void setOutput(String output) {
        this.output = output;
    }
    public String getOutputMessage() {
        return outputMessage;
    }
    public void setOutputMessage(String outputMessage) {
        this.outputMessage = outputMessage;
    }
    public String getPredictorStats() {
        return predictorStats;
    }
    public void setPredictorStats(String predictorStats) {
        this.predictorStats = predictorStats;
    }
    public void decodeString(String runResult) throws Exception {
        SapforResult_json resultJson = Utils_.gson.fromJson(runResult, SapforResult_json.class);
        //---
        setErrorCode(resultJson.errorCode);
        setOutput(resultJson.output);
        setResult(resultJson.result);
        setOutputMessage(resultJson.outputMessage);
        setPredictorStats(resultJson.predictorStats);
        //--
        if (resultJson.files!=null && !resultJson.files.isEmpty()){
            for (ModifiedFile_json file: resultJson.files){
                ModifiedFiles.put(Utils_.toW(file.name), file.text);
            }
        }
        //--
        /*
        int codeIdx = runResult.indexOf(' ');
        if (codeIdx == -1) throw new PassException("Wrong input parameter");
        setErrorCode(Integer.parseInt(runResult.substring(0, codeIdx)));
        int lastCodeIdx = 0, count = 0;
        // for analysis and transformation
        for (int z = 0; z < 4; ++z) {
            lastCodeIdx = codeIdx;
            codeIdx = runResult.indexOf(' ', codeIdx + 1);
            if (codeIdx == -1) throw new PassException("Wrong input parameter");
            count = Integer.parseInt(runResult.substring(lastCodeIdx + 1, codeIdx));
            String sub = runResult.substring(codeIdx + 1, codeIdx + 1 + count);
            if (z == 0) setResult(sub);
            else if (z == 1) setOutput(sub);
            else if (z == 2) setOutputMessage(sub);
            else if (z == 3) setPredictorStats(sub);
            codeIdx += count;
        }
        // for modification
        String file_text = null;
        if (codeIdx + 1 + count < runResult.length())
            for (int z = 0; z < 3; ++z) {
                lastCodeIdx = codeIdx;
                codeIdx = runResult.indexOf(' ', codeIdx + 1);
                if (codeIdx == -1) throw new PassException("Wrong input parameter");
                count = Integer.parseInt(runResult.substring(lastCodeIdx + 1, codeIdx));
                String sub = runResult.substring(codeIdx + 1, codeIdx + 1 + count);
                if (z == 0) {
                    String[] splited = sub.split("\\|");
                    if (splited.length == 0 || sub.length() == 0)
                        size = 0;
                    else {
                        size = splited.length - 1;
                        sizes = new int[splited.length];
                        for (int k = 0; k < size + 1; ++k)
                            sizes[k] = Integer.parseInt(splited[k]);
                    }
                } else if (z == 1) file_text = sub;
                else if (z == 2) {
                    ModifiedFiles.put(Utils_.toW(sub), file_text);
                    file_text = null;
                }
                codeIdx += count;
            }
         */
    }
    //-
    public void Command(String request_in) throws Exception {
        setErrorCode(empty_code);
        outputMessage = output = result = predictorStats = "";
        ModifiedFiles.clear();
        //модификации.-------------------------------------------------------------->>>>
        decodeString(Global.visualizer_2.Command(request_in).replace((char) 1, '\n'));
    }
    //-
    public int RunAnalysis(String analysisName,
                           int winHandler,
                           String options,
                           String projName) throws Exception {
        Command("analysis:" + pack(analysisName, options, projName) + winHandler);
        return getErrorCode();
    }
    public void RunTransformation(String transformName,
                                  int winHandler,
                                  String options,
                                  String projName,
                                  String folderName,
                                  String addOpts) throws Exception {
        Command("transformation:" + pack(transformName, options, projName, folderName, addOpts) + winHandler);
    }
    public void RunModification(String modifyName, int winHandler, String options, String projName,
                                String folderName, String addOpt1, String addOpt2) throws Exception {
        Command("modification:" + pack(modifyName, options, projName, folderName, addOpt1, addOpt2) + winHandler);
    }
    //--
      /*
     Модификации:
    SPF_ModifyArrayDistribution (addOpt1_c -> regId, addOpt2_c-> int64_t arrArrs, '|' as delimiter)
    SPF_InlineProcedure (addOpt1_c -> name | file, addOpt2_c-> line)
    */
    //--
    public void GetIntrinsics() throws Exception {
        Intrinsics.clear();
        if (RunAnalysis("SPF_GetIntrinsics", -1, "", "") >= 0) {
            String[] data = getResult().split(" ");
            Collections.addAll(Intrinsics, data);
        }
    }
    public boolean isIntrinsic(String func_name) {
        return Intrinsics.contains(func_name.toLowerCase());
    }
    //todo рефакторить. отвязать от текущего проекта.
    public void UpdateProjectFiles(boolean mode) throws Exception {
        ResetAllAnalyses();
        Global.mainModule.getProject().dropLastModification();
        DBProjectFile cuf = null;
        if (Global.mainModule.HasFile()) {
            cuf = Global.mainModule.getFile();
            Global.mainModule.getPass(PassCode.CloseCurrentFile).Do();
        }
        if (mode) //модификация
        {
            OldFiles.clear();
            for (String name : ModifiedFiles.keySet()) {
                if (Global.mainModule.getProject().db.files.Data.containsKey(name)) {
                    File file = Global.mainModule.getProject().db.files.Data.get(name).file;
                    OldFiles.put(name, Utils.ReadAllText(file));
                    Utils.WriteToFile(file, ModifiedFiles.get(name));
                }
            }
            ModifiedFiles.clear();
        } else //откат.
        {
            if (OldFiles.size() > 0) {
                for (String name : OldFiles.keySet()) {
                    File file = Global.mainModule.getProject().db.files.Data.get(name).file;
                    Utils.WriteToFile(file, OldFiles.get(name));
                }
                OldFiles.clear();
            } else UI.Info("Сохранение файлов отсутствует.");
        }
        if (cuf != null)
            Global.mainModule.getPass(PassCode.OpenCurrentFile).Do(cuf);
    }
    //</editor-fold>
    public SapforAnalysis getAnalysisByPhase(String phase) {
        for (PassCode analysis_code : getAnalysesCodes()) {
            SapforAnalysis analysis = (SapforAnalysis) Global.mainModule.getPass(analysis_code);
            if (analysis.phase().equals(phase)) return analysis;
        }
        return null;
    }
    public void ResetAllAnalyses() {
        for (PassCode code : getAnalysesCodes())
            (Global.mainModule.getPass(code)).Reset();
        //------------------------------------------------------------------------------------------>>>> пакетный режим.
        if (UI.isActive()) {
            Global.mainModule.getPass(PassCode.Precompilation).Reset();
            Global.mainModule.getPass(PassCode.SPF_GetGCovInfo).Reset();
        }
        SPFEditor.enable_text_changed = false;
        transformationPermission = TransformationPermission.None;
        if ((UI.isActive()) && (Global.mainModule.getUI().hasMainWindow()) && (Global.mainModule.getUI().getVersionsWindow() != null))
            Global.mainModule.getUI().getVersionsWindow().BlockVariants();
    }
    //--
}
