package _VisualDVM.Passes.Sapfor;
import Common.Passes.PassState;
import Common.Utils.Utils_;
import Common.Visual.Controls.PassControl;
import Common.Visual.Controls.PassMenuItem;
import Common.Visual.UI;
import _VisualDVM.Global;
import _VisualDVM.Passes.PassCode;

import javax.swing.*;
import java.awt.event.ActionEvent;
import java.util.Vector;
public class SapforAnalysis extends SapforPass {
    boolean asDonePhase = false;
    protected Vector<String> getForbiddenPhases() {
        return new Vector<>();
    }
    @Override
    protected boolean needsAnimation() {
        return super.needsAnimation() && !asDonePhase;
    }
    @Override
    protected boolean canStart(Object... args) throws Exception {
        asDonePhase = false;
        if (super.canStart(args)) {
            asDonePhase = ((args.length >= 1) && ((boolean) args[0]));
            return true;
        }
        return false;
    }
    public String phase() {
        return "";
    }
    @Override
    protected PassCode necessary() {
        return PassCode.SPF_ParseFilesWithOrder;
    }
    @Override
    public String getIconPath() {
        return "/Common/icons/NotPick.png";
    }
    protected String getDoneIconPath() {
        return "/Common/icons/Pick.png";
    }
    @Override
    protected boolean isGoodCode() {
        return sapfor.getErrorCode() > 0;
    }
    @Override
    protected void PerformPreparation() throws Exception {
        //-
        if (UI.isActive())
            showPreparation(); // отображение пустых данных
        //-
        performPreparation(); //в данном случае удаление данных
        //-
        //особенность отрисовки местных контролов.
        //если сначала удалить данные, то контролы могут обновиться и сослаться на несуществующие
        //поэтому сначала блокируем контролы, потом удаляем.
    }
    @Override
    protected void body() throws Exception {
        sapfor.RunAnalysis(
                getSapforPassName(),
                -Global.messagesServer.getPort(),
                target.sapforProperties.pack(),
                target.getProjFile().getAbsolutePath());
    }
    protected void unpack(String packed) throws Exception {
    }
    //---------------------------------------------
    //всегда обновлять фазу, даже если она уже выполнена.
    protected boolean alwaysCheck() {
        return false;
    }
    protected boolean isAtomic() {
        return true;
    }
    //атомарность означает что анализ не ищет фаз.
    @Override
    protected void performDone() throws Exception {
        if (!sapfor.getResult().isEmpty()) {
            unpack(sapfor.getResult());
        }
        if (!isAtomic() && !asDonePhase) {
            Utils_.MainLog.Print("Поиск выполненных фаз..");
            sapfor.RunAnalysis(
                    "SPF_GetPassesStateStr",
                    -Global.messagesServer.getPort(),
                    "",
                    "");
            if (sapfor.getErrorCode() >= 0) {
                String[] arrayPasses = sapfor.getResult().split("\\|");
                // "FILL_PAR_REGIONS_LINES" всегда брать последним, чтобы информация была актуальна.
                Vector<String> sortedPasses = new Vector<>();
                boolean needsRegions = false;
                for (String p : arrayPasses) {
                    if (p.equals("FILL_PAR_REGIONS_LINES"))
                        needsRegions = true;
                    else
                        sortedPasses.add(p);
                }
                if (needsRegions)
                    sortedPasses.add("FILL_PAR_REGIONS_LINES");
                for (String p : sortedPasses) {
                    if (!p.isEmpty() && !phase().equals(p)) {
                        SapforAnalysis analysis =
                                sapfor.getAnalysisByPhase(p);
                        if ((analysis != null) && (!analysis.getName().equals(getName())) && (analysis.alwaysCheck() || !analysis.isDone())) {
                            if (getForbiddenPhases().contains(analysis.getName())) {
                                analysis.setDone();
                                analysis.MarkAsDone();
                            } else
                                analysis.start(true);
                        }
                    }
                }
            }
            Utils_.MainLog.Print("Фазы получены.");
        }
    }
    //---------------------------------------------
    @Override
    public void Reset() {
        if (state == PassState.Done) {
            state = PassState.Inactive;
            for (PassControl control : controls)
                control.setIcon(getIconPath());
        }
    }
    public void MarkAsDone() {
        for (PassControl control : controls)
            control.setIcon(getDoneIconPath());
    }
    @Override
    protected void showDone() throws Exception {
        MarkAsDone();
    }
    @Override
    public AbstractAction getControlAction() {
        return new AbstractAction() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if (isDone()) FocusResult();
                else {
                    UpdateStatsIfNeed();
                    Do();
                }
            }
        };
    }
    @Override
    public boolean hasStats() {
        return true;
    }
    @Override
    protected void FocusResult() {
        Global.mainModule.getUI().getMainWindow().FocusProject();
    }
    @Override
    protected void unpackMessages() throws Exception {
        if (!asDonePhase) super.unpackMessages();
    }
    @Override
    protected void showFinish() throws Exception {
        if (!asDonePhase)
            super.showFinish();
    }
    @Override
    public JMenuItem createMenuItem() {
        if (menuItem == null)
            menuItem = new PassMenuItem(this);
        return menuItem;
    }
}
