package _VisualDVM.TestingSystem.SAPFOR.Json;
import Common.CommonConstants;
import _VisualDVM.Global;
import _VisualDVM.GlobalData.Tasks.TaskState;
import _VisualDVM.TestingSystem.Common.Test.Test;
import _VisualDVM.TestingSystem.SAPFOR.SapforConfiguration.SapforConfiguration;
import _VisualDVM.TestingSystem.SAPFOR.SapforPackage.SapforPackage;
import _VisualDVM.TestingSystem.SAPFOR.SapforTask.ComparisonState;
import _VisualDVM.TestingSystem.SAPFOR.SapforTask.SapforTask;
import _VisualDVM.TestingSystem.SAPFOR.SapforTasksPackage.UI.PackageComparisonSummary;
import _VisualDVM.TestingSystem.SAPFOR.SapforTasksPackage.UI.PackageSummary;
import _VisualDVM.TestingSystem.SAPFOR.ServerSapfor.ServerSapfor;
import com.google.gson.annotations.Expose;

import javax.swing.tree.DefaultMutableTreeNode;
import java.io.File;
import java.io.Serializable;
import java.nio.file.Paths;
import java.util.Comparator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Vector;
public class SapforPackage_json implements Serializable {
    @Expose
    public int kernels = 1;
    @Expose
    public String sapfor_drv = ""; //файл с сапфором. Имя уникально для сценария.
    //--
    @Expose
    public int max_set_id = 0;
    @Expose
    public int max_task_id = 0;
    //--в отличие от пакета двм,где достаточно инфы о задачах, тут есть инфа о тестах и конфигурациях
    @Expose
    public List<SapforTestingSet_json> testingSets = new Vector<>(); //по факту, сет один. Наследие формирования пакетов.
    @Expose
    public List<SapforTask> tasks = new Vector<>();
    //-
    public PackageSummary root = null;
    public PackageComparisonSummary comparison_root = null;
    //---
    public SapforPackage_json() {
    }
    public SapforPackage_json(ServerSapfor serverSapfor, Vector<SapforConfiguration> configurations, int kernels_in) {
        sapfor_drv = serverSapfor.call_command;
        kernels = kernels_in;
        for (SapforConfiguration sapforConfiguration : configurations) {
            Vector<Test> tests = new Vector<Test>();
            for (int test_id : Global.testingServer.db.getSapforConfigurationTestsIds(sapforConfiguration)) {
                tests.add(Global.testingServer.db.tests.get(test_id));
            }
            SapforTestingSet_json testingSet = new SapforTestingSet_json(tests, sapforConfiguration);
            testingSet.id = getMaxSetId();
            testingSets.add(testingSet);
            // формирование задач
            LinkedHashMap<String, SapforTask> sortedTasks = new LinkedHashMap<>();
            //здесь из за совместимости. на самом деле это параметры а не конфигурации. но название старое.
            for (SapforConfiguration_json sapforConfiguration_json : testingSet.configurations) {
                for (SapforTest_json test : testingSet.tests) {
                    SapforTask task = new SapforTask(testingSet, test, sapforConfiguration_json);
                    if (!sortedTasks.containsKey(task.getUniqueKey())) {
                        task.id = getMaxTaskId();
                        sortedTasks.put(task.getUniqueKey(), task);
                    }
                }
            }
            tasks.addAll(sortedTasks.values());
        }
    }
    public int getMaxSetId() {
        return max_set_id++;
    }
    public int getMaxTaskId() {
        return max_task_id++;
    }
    //--
    public Vector<String> getTasksKeys() {
        Vector<String> keys = new Vector<>();
        for (SapforTask task : tasks) {
            String key = task.getUniqueKey();
            if (!keys.contains(key))
                keys.add(key);
        }
        return keys;
    }
    public Vector<String> getTestsNames() {
        Vector<String> names = new Vector<>();
        for (SapforTask task : tasks) {
            if (!names.contains(task.test_description))
                names.add(task.test_description);
        }
        names.sort(new Comparator<String>() {
            @Override
            public int compare(String o1, String o2) {
                return o1.compareTo(o2);
            }
        });
        return names;
    }
    //--
    public void sortTasks() {
        tasks.sort(new Comparator<SapforTask>() {
            @Override
            public int compare(SapforTask o1, SapforTask o2) {
                return Integer.compare(o1.state.ordinal(), o2.state.ordinal());
            }
        });
    }
    public void sortTasksForComparison() {
        tasks.sort(new Comparator<SapforTask>() {
            @Override
            public int compare(SapforTask o1, SapforTask o2) {
                return Integer.compare(o1.comparisonState.ordinal(), o2.comparisonState.ordinal());
            }
        });
    }
    public boolean containsKey(String key) {
        for (SapforTask task : tasks) {
            if (task.getUniqueKey().equals(key))
                return true;
        }
        return false;
    }
    public SapforTask getTaskByKey(String key) {
        for (SapforTask task : tasks) {
            if (task.getUniqueKey().equals(key))
                return task;
        }
        return null;
    }
    //---------
    public void DropComparison() {
        comparison_root = null;
        for (SapforTask task : tasks) {
            task.comparisonState = ComparisonState.Unknown;
            for (SapforVersion_json version : task.versions)
                version.comparisonState = VersionComparisonState.Unknown;
            for (SapforVersion_json version : task.variants)
                version.comparisonState = VersionComparisonState.Unknown;
        }
    }
    public void buildTree(SapforPackage package_in) {
        //--
        root = new PackageSummary();
        root.count = tasks.size();
        root.errors_count = 0;
        //--
        sortTasks();
        //--
        for (SapforTask task : tasks) {
            DefaultMutableTreeNode taskNode = task.getNode(Paths.get(
                    package_in.getLocalWorkspace().getAbsolutePath(),
                    String.valueOf(task.set_id),
                    String.valueOf(task.sapfor_configuration_id)
            ).toFile());
            root.add(taskNode);
            if (!task.state.equals(TaskState.Done))
                root.errors_count++;
        }
    }
    public int buildComparisonTree(SapforPackage package_in) {
        comparison_root = new PackageComparisonSummary();
        comparison_root.count = tasks.size();
        comparison_root.mismatches_count = 0;
        //--
        sortTasksForComparison();
        //--
        for (SapforTask task : tasks) {
            DefaultMutableTreeNode taskNode = task.getNode(Paths.get(
                    package_in.getLocalWorkspace().getAbsolutePath(),
                    String.valueOf(task.set_id),
                    String.valueOf(task.sapfor_configuration_id)
            ).toFile());
            comparison_root.add(taskNode);
            if (task.comparisonState.equals(ComparisonState.NotMatch))
                comparison_root.mismatches_count++;
        }
        return comparison_root.mismatches_count;
    }
    public void getVersionsFiles(SapforPackage package_in) {
        //---
        //---
        for (SapforTask task : tasks) {
            File configurationRoot = Paths.get(
                    package_in.getLocalWorkspace().getAbsolutePath(),
                    String.valueOf(task.set_id),
                    String.valueOf(task.sapfor_configuration_id)
            ).toFile();
            for (SapforVersion_json version_json : task.versions) {
                version_json.task = task;
                version_json.getFiles(configurationRoot);
            }
            for (SapforVersion_json version_json : task.variants) {
                version_json.task = task;
                version_json.getFiles(configurationRoot);
            }
        }
    }
    public Vector<String> getConfigurationsNames() {
        Vector<String> names = new Vector<>();
        for (SapforTestingSet_json set : testingSets) {
            for (SapforConfiguration_json configurationJson : set.configurations) {
                if (!names.contains(configurationJson.name))
                    names.add(configurationJson.name);
            }
        }
        names.sort(new Comparator<String>() {
            @Override
            public int compare(String o1, String o2) {
                return o1.compareTo(o2);
            }
        });
        return names;
    }
    public int getConfigurationId() {
        if (testingSets.size() == 1) {
            SapforTestingSet_json testingSet_json = testingSets.get(0);
            if (testingSet_json.configurations.size() == 1) {
                return testingSet_json.configurations.get(0).id;
            }
        }
        return CommonConstants.Nan;
    }
}
