package _VisualDVM.TestingSystem.SAPFOR.SapforTask;
import Common.CommonConstants;
import Common.Database.Objects.DBObject;
import Common.Utils.Utils_;
import _VisualDVM.GlobalData.Tasks.TaskState;
import _VisualDVM.Passes.PassCode;
import _VisualDVM.TestingSystem.SAPFOR.Json.*;
import _VisualDVM.TestingSystem.SAPFOR.SapforTasksPackage.UI.SapforPackageTreeNode;
import _VisualDVM.TestingSystem.SAPFOR.SapforTasksPackage.UI.SapforTaskNode;
import _VisualDVM.TestingSystem.SAPFOR.SapforTasksPackage.UI.VersionNode;
import com.google.gson.annotations.Expose;
import com.sun.org.glassfish.gmbal.Description;

import javax.swing.tree.DefaultMutableTreeNode;
import java.io.File;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.Vector;
public class SapforTask extends DBObject {
    //------------------------------------>>
    @Expose
    public long id = CommonConstants.Nan;
    @Expose
    public int set_id = 0;
    @Expose
    public int sapfor_configuration_id = CommonConstants.Nan;
    @Expose
    public long sapfortaskspackage_id = CommonConstants.Nan;
    //------------------------------------->>
    @Expose
    public String test_description = "";
    @Expose
    public String group_description = "";
    @Expose
    public String configuration_description = "";
    @Expose
    public String flags = "";
    @Expose
    public String codes = "";
    @Expose
    public long StartDate = 0; //дата начала выполнения
    @Expose
    public long ChangeDate = 0;//дата окончания выполнения
    //в json не выносить. это только для БД.
    @Description("DEFAULT ''")
    public String versionsDescription = "";
    //------
    @Description("IGNORE")
    @Expose
    public Vector<SapforVersion_json> versions = new Vector<>();
    //----------
    @Description("IGNORE")
    @Expose
    public Vector<SapforVersion_json> variants = new Vector<>();
    //-------------------------------------------------
    @Expose
    public TaskState state = TaskState.Inactive;
    @Description("IGNORE")
    public ComparisonState comparisonState = ComparisonState.Unknown;  //для сравнения. в обычном режиме всегда Unknown!
    //-----------
    public SapforTask() {
    }
    public SapforTask(SapforTask src) {
        this.SynchronizeFields(src);
    }
    //-
    public SapforTask(SapforTestingSet_json testingSet, SapforTest_json test, SapforConfiguration_json sapforConfiguration_json) {
        id = CommonConstants.Nan;
        set_id = testingSet.id;
        sapfortaskspackage_id = CommonConstants.Nan;
        //-- unique key--
        group_description = test.group_description;
        test_description = test.description;
        configuration_description = sapforConfiguration_json.name;
        sapfor_configuration_id = sapforConfiguration_json.id;
        //---------------
        flags = sapforConfiguration_json.flags;
        Vector<String> codes_s = new Vector<>();
        for (PassCode code : sapforConfiguration_json.codes)
            codes_s.add(code.toString());
        codes = String.join(" ", codes_s);
    }
    //--------------------------------------------------
    public String getUniqueKey() {
        return group_description + "_" + test_description + "_" + sapfor_configuration_id;
    }
    public String getSummary() {
        Vector<String> lines = new Vector<>();
        lines.add(group_description);
        lines.add(test_description);
        lines.add(codes);
        lines.add(flags);
        return String.join(" ", lines);
    }
    public void Reset() {
        state = TaskState.Inactive;
        versions.clear();
        variants.clear();
    }
    @Override
    public Object getPK() {
        return id;
    }
    @Override
    public void SynchronizeFields(DBObject object) {
        super.SynchronizeFields(object);
        SapforTask t = (SapforTask) object;
        id = t.id;
        set_id = t.set_id;
        sapfor_configuration_id = t.sapfor_configuration_id;
        sapfortaskspackage_id = t.sapfortaskspackage_id;
        //-
        test_description = t.test_description;
        group_description = t.group_description;
        configuration_description = t.configuration_description;
        versionsDescription = t.versionsDescription;
        //--
        codes = t.codes;
        state = t.state;
        //--
    }
    public String getVersionsChain() {
        Vector<String> versionsLines = new Vector<>();
        for (int i = 1; i < versions.size(); ++i) {
            versionsLines.add(Utils_.Brackets(versions.get(i).description));
        }
        if (!variants.isEmpty()) {
            versionsLines.add(Utils_.Brackets(PassCode.CreateParallelVariants.getDescription()));
        }
        return String.join("→", versionsLines);
    }
    public LinkedHashMap<String, SapforVersion_json> getSortedVersions() {
        LinkedHashMap<String, SapforVersion_json> res = new LinkedHashMap<>();
        for (SapforVersion_json version_json : versions)
            res.put(version_json.version, version_json);
        //--
        for (SapforVersion_json variant_json : variants)
            res.put(variant_json.version, variant_json);
        return res;
    }
    public void checkMatch(SapforTask task2) {
        if (!state.equals(task2.state)) {
            comparisonState = ComparisonState.NotMatch;
            task2.comparisonState = ComparisonState.NotMatch;
        }
        if ((versions.size() != task2.versions.size()) || (variants.size() != task2.variants.size())) {
            comparisonState = ComparisonState.NotMatch;
            task2.comparisonState = ComparisonState.NotMatch;
        }
        LinkedHashMap<String, SapforVersion_json> versions1 = getSortedVersions();
        LinkedHashMap<String, SapforVersion_json> versions2 = task2.getSortedVersions();
        //---
        for (String name1 : versions1.keySet()) {
            if (versions2.containsKey(name1)) {
                SapforVersion_json version1 = versions1.get(name1);
                SapforVersion_json version2 = versions2.get(name1);
                //---
                if (!version1.isMatch(version2)) {
                    comparisonState = ComparisonState.NotMatch;
                    task2.comparisonState = ComparisonState.NotMatch;
                    version1.comparisonState = VersionComparisonState.NotMatch;
                    version2.comparisonState = VersionComparisonState.NotMatch;
                    //-
                } else {
                    version1.comparisonState = VersionComparisonState.Match;
                    version2.comparisonState = VersionComparisonState.Match;
                    //-
                }
            } else {
                comparisonState = ComparisonState.NotMatch;
                task2.comparisonState = ComparisonState.NotMatch;
                //--
            }
        }
        //--
        if (comparisonState.equals(ComparisonState.Unknown)) {
            comparisonState = ComparisonState.Match;
            task2.comparisonState = ComparisonState.Match;
        }
    }
    public Date getStartDate() {
        return new Date(StartDate);
    }
    public Date getChangeDate() {
        return new Date(ChangeDate);
    }
    @Override
    public String toString() {
        return
                "#" + id + " группа "
                        + Utils_.Brackets(group_description) +
                        " тест " + Utils_.Brackets(test_description)
                        + " параметры "
                        + Utils_.Brackets(configuration_description.isEmpty() ? sapfor_configuration_id : configuration_description);
        //   getUniqueKey();
    }
    public String getPassesInfo() {
        String res = "";
        String[] data = codes.split(" ");
        Vector<String> strings = new Vector<>();
        for (String code_s : data) {
            PassCode code = PassCode.valueOf(code_s);
            strings.add(Utils_.Brackets(code.getDescription()));
        }
        return String.join("→", strings);
    }
    //---
    public DefaultMutableTreeNode getVersionsTree() {
        VersionNode root = null;
        VersionNode child = null;
        VersionNode parent = null;
        //--
        for (SapforVersion_json version_json : versions) {
            version_json.task = this;
            child = new VersionNode(version_json);
            if (parent == null) {
                root = child;
                parent = child;
            } else {
                parent.add(child);
                parent = child;
            }
            //-
        }
        if (parent != null) {
            for (SapforVersion_json version_json : variants) {
                version_json.task = this;
                parent.add(new VersionNode(version_json));
            }
        }
        //--
        return root;
    }
    //---
    public DefaultMutableTreeNode getNode(File configurationRoot) {
        SapforPackageTreeNode res = new SapforTaskNode(this);
        //-
        DefaultMutableTreeNode flags_info = new DefaultMutableTreeNode("флаги: " + this.flags);
        DefaultMutableTreeNode passes_info = new DefaultMutableTreeNode("проходы: " + getPassesInfo());
        //-
        int total_versions_count = versions.size() + variants.size();
        DefaultMutableTreeNode versions_info = new DefaultMutableTreeNode("версии: " + total_versions_count);
        versions_info.add(getVersionsTree());
        res.add(flags_info);
        res.add(passes_info);
        res.add(versions_info);
        return res;
    }
}
