package _VisualDVM.TestingSystem.SAPFOR.SapforSettings;
import Common.Database.Objects.DBObject;
import Common.Utils.TextLog;
import Common.Utils.Utils_;
import _VisualDVM.Global;
import _VisualDVM.Passes.PassCode;
import _VisualDVM.TestingSystem.Common.Settings.Settings;
import _VisualDVM.TestingSystem.SAPFOR.SapforSettingsCommand.SapforSettingsCommand;

import java.util.List;
import java.util.Vector;
public class SapforSettings extends Settings {
    //настройки.
    public int FREE_FORM = 0; //"Свободный выходной стиль"; -f90
    public int STATIC_SHADOW_ANALYSIS = 0;//"Оптимизация теневых обменов"; -sh
    public int MAX_SHADOW_WIDTH = 50; // "Максимальный размер теневых граней"; (%) -shwidth значение поля
    public int KEEP_SPF_DIRECTIVES = 0; //"Сохранять SPF директивы при построении параллельных вариантов"; -keepSPF
    public int KEEP_DVM_DIRECTIVES = 0;// "Учитывать DVM директивы"; -keepDVM
    //-
    public String flags = "";
    //-
    public SapforSettings(SapforSettings sapforSettings) {
        this.SynchronizeFields(sapforSettings);
    }
    public SapforSettings() {
    }
    //----
    //----
    public void packFlags() {
        Vector<String> res = new Vector<>();
        //--
        if (FREE_FORM > 0)
            res.add("-f90");
        if (STATIC_SHADOW_ANALYSIS > 0)
            res.add("-sh");
        if (MAX_SHADOW_WIDTH > 0)
            res.add("-shwidth " + MAX_SHADOW_WIDTH);
        if (KEEP_DVM_DIRECTIVES > 0)
            res.add("-keepDVM");
        if (KEEP_SPF_DIRECTIVES > 0)
            res.add("-keepSPF");
        //--
        flags = String.join(" ", res);
    }
    //--
    @Override
    public void SynchronizeFields(DBObject src) {
        super.SynchronizeFields(src);
        SapforSettings c = (SapforSettings) src;
        FREE_FORM = c.FREE_FORM;
        STATIC_SHADOW_ANALYSIS = c.STATIC_SHADOW_ANALYSIS;
        MAX_SHADOW_WIDTH = c.MAX_SHADOW_WIDTH;
        KEEP_SPF_DIRECTIVES = c.KEEP_SPF_DIRECTIVES;
        KEEP_DVM_DIRECTIVES = c.KEEP_DVM_DIRECTIVES;
        flags = c.flags;
    }
    public Vector<PassCode> getCodes() {
        Vector<PassCode> res = new Vector<>();
        for (SapforSettingsCommand command : Global.testingServer.db.sapforSettingsCommands.Data.values())
            if (command.sapforsettings_id == id) res.add(command.passCode);
        return res;
    }
    public List<PassCode> getCheckedCodes() {
        Vector<PassCode> res = getCodes();
        if (!res.firstElement().equals(PassCode.SPF_InsertIncludesPass))
            res.insertElementAt(PassCode.SPF_CorrectCodeStylePass, 0); //всегда добавляется.
        return res;
    }
    @Override
    public boolean validate(TextLog Log) {
        boolean res = true;
        Vector<PassCode> codes = getCodes();
        if (codes.size() == 0) {
            Log.Writeln_("Настройки:" + id + " не содержат ни одного прохода.");
            return false;
        }
        //-
        int first = 0;
        int last = codes.size() - 1;
        Vector<PassCode> matches = new Vector<>();
        for (int i = 0; i < codes.size(); ++i) {
            PassCode code = codes.get(i);
            if (code.isSapforStart()) {
                if (i > first) {
                    Log.Writeln_("Неверные настройки:" + id + ": проход" +
                            Utils_.Brackets(code.getDescription()) +
                            " может быть только первым!");
                    res = false;
                }
            }
            if (code.isSapforTerminal()) {
                if (i < last) {
                    Log.Writeln_("Неверные настройки:" + id + ": проход " +
                            Utils_.Brackets(code.getDescription()) +
                            " может быть только последним!");
                    res = false;
                }
            }
            if (matches.contains(code)) {
                Log.Writeln_("Неверные настройки:" + id + ": проход " +
                        Utils_.Brackets(code.getDescription()) +
                        " запрещено применять более одного раза!");
                res = false;
            } else matches.add(code);
        }
        //-
        return res;
    }
}
