package _VisualDVM.Visual.Windows;
import Common.Database.Objects.DBObject;
import Common.Passes.Pass;
import Common.Utils.TextLog;
import Common.Visual.Controls.ShortLabel;
import Common.Visual.Menus.VisualiserMenuBar;
import Common.Visual.UI;
import _VisualDVM.Current;
import _VisualDVM.Global;
import _VisualDVM.Passes.PassCode;
import _VisualDVM.TestingSystem.SAPFOR.SapforPackage.SapforPackage;
import _VisualDVM.TestingSystem.SAPFOR.SapforTask.SapforTask;
import _VisualDVM.TestingSystem.SAPFOR.SapforTasksPackage.UI.SapforTasksPackageTree;

import javax.swing.*;
import java.util.concurrent.ForkJoinPool;
public class SapforPackagesComparisonForm {
    public boolean comparisonMode = false;
    public JScrollPane treeScroll = null;
    protected JToolBar tools;
    protected JLabel lObjectName;
    //-->>
    protected SapforPackage object = null;
    //-->>
    protected SapforTasksPackageTree Body;
    //-->>
    SapforPackagesComparisonForm this_ = null; //?
    SapforPackagesComparisonForm slave = null;
    SapforPackagesComparisonForm master = null;
    //-->>
    private JPanel content;
    private JButton bApplyObject;
    private JButton bPrevious;
    private JButton bNext;
    private JButton bCompare;
    private JButton bClose;
    private JPanel treePanel;
    public SapforPackagesComparisonForm(SapforPackagesComparisonForm slave_in) {
        //-
        this_ = this;
        slave = slave_in;
        bPrevious.setVisible(isMaster());
        bNext.setVisible(isMaster());
        bApplyObject.addActionListener(e -> {
            ApplyObject();
        });
        //--->>>
        if (isMaster()) {
            slave.master = this;
            bPrevious.addActionListener(e -> {
            });
            bNext.addActionListener(e -> {
            });
            bCompare.addActionListener(e -> {
                DoComparePass();
            });
        } else {
            //рабу сравнивать не положено.
            bCompare.setVisible(false);
        }
        //--->>>
        bClose.addActionListener(e -> {
            onClose();
        });
    }
    public JPanel getContent() {
        return content;
    }
    //--->>
    public boolean isMaster() {
        return slave != null;
    }
    public boolean isSlave() {
        return master != null;
    }
    //--->>
    //неперегружаемые методы
    protected void RemoveObject() {
        object = null;
        showNoObject();
        //--
        if (comparisonMode) {
            comparisonMode = false;
            if (isMaster()) {
                slave.comparisonMode = false;
                slave.object = null;
                slave.showNoObject();
            } else {
                master.comparisonMode = false;
                master.object = null;
                master.showNoObject();
            }
        }
    }
    public void ApplyObject() {
        //---Загрузка
        RemoveObject();
        //---
        TextLog log = new TextLog();
        if (Global.testingServer.db.sapforPackages.getUI().CheckCurrent(log)) {
            object = Global.testingServer.db.sapforPackages.getUI().getCurrent();
            if (object.isLoaded() || (Global.mainModule.getPass(PassCode.DownloadSapforPackage).Do(object))) {
                showObject();
            }
        } else
            UI.Info(log.toString());
    }
    public void ApplyObject(DBObject object_in) {
        RemoveObject();
        object = (SapforPackage) object_in;
        if (object.isLoaded() || (Global.mainModule.getPass(PassCode.DownloadSapforPackage).Do(object))) {
            showObject();
        }
    }
    public void Show() throws Exception {
    }
    public void showNoObject() {
        lObjectName.setText("?");
        lObjectName.setToolTipText("Объект не назначен.");
        showNoTree();
        if (isMaster()) {
            Global.mainModule.getUI().getMainWindow().getTestingWindow().ShowNoSapforPackageVersionEtalon();
        } else {
            Global.mainModule.getUI().getMainWindow().getTestingWindow().ShowNoSapforPackageVersion();
        }
    }
    //---
    public void showCommonTree() {
        //---
        treePanel.add(treeScroll = new JScrollPane(
                Body = new SapforTasksPackageTree(object.package_json.root,
                        isMaster() ? Current.SapforEtalonVersion : Current.SapforVersion
                )));
        treePanel.repaint();
        treePanel.revalidate();
    }
    public void showComparisonTree() {
        treePanel.add(treeScroll = new JScrollPane(
                Body = new SapforTasksPackageTree(object.package_json.comparison_root,
                        isMaster() ? Current.SapforEtalonVersion : Current.SapforVersion
                )));
        treePanel.repaint();
        treePanel.revalidate();
    }
    //---
    public void showNoTree() {
        UI.Clear(treePanel);
    }
    public void showObject() {
        lObjectName.setText(object.getPK().toString() + (isMaster() ? "(эталон)" : ""));
        lObjectName.setToolTipText(object.getPK().toString());
        //--
        if (object.package_json == null) {
            try {
                System.out.println(object.getPK() + " reading json");
                object.readJson();
                System.out.println("done");
                System.out.println(object.getPK() + " reading files");
                object.package_json.getVersionsFiles(object);
                object.package_json.buildTree(object);
                System.out.println(object.getPK() + " done");
                //---
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
        object.package_json.DropComparison();
        //--
        showCommonTree();
    }
    protected String getText() {
        return "";
    }
    //-->>
    private void createUIComponents() {
        // TODO: place custom component creation code here
        lObjectName = new ShortLabel(40);
        tools = new VisualiserMenuBar();
    }
    //для сравнения по кнопке.
    public boolean isReady() {
        return object != null;
    }
    public void onClose() {
        RemoveObject();
    }
    public void DoComparePass() {
        Pass pass = new Pass() {
            SapforPackage package1;
            SapforPackage package2;
            @Override
            public String getDescription() {
                return "Сравнение";
            }
            @Override
            protected boolean needsAnimation() {
                return true;
            }
            @Override
            public boolean needsConfirmations() {
                return false;
            }
            @Override
            protected boolean canStart(Object... args) throws Exception {
                if (isReady() && slave.isReady()) {
                    //--
                    package1 = object;
                    package2 = slave.object;
                    //--
                    if (package1.package_json.tasks.size() != package2.package_json.tasks.size()) {
                        Log.Writeln_("Количество задач в пакетах не совпадает!");
                        return false;
                    }
                    //todo  в дереве отображать пустые задачи заместо тех кого не хватает.
                    for (SapforTask task1 : package1.package_json.tasks) {
                        if (!package2.package_json.containsKey(task1.getUniqueKey()))
                            Log.Writeln_("Задача эталона " + task1.getUniqueKey() + "не найдена в сравниваемом пакете!");
                    }
                    return Log.isEmpty();
                }
                return false;
            }
            @Override
            protected void performPreparation() throws Exception {
                comparisonMode = false;
                slave.comparisonMode = false;
                //--
                treeScroll = null;
                slave.treeScroll = null;
                //--
                package1.package_json.DropComparison();
                package2.package_json.DropComparison();
            }
            @Override
            protected void showPreparation() throws Exception {
                showNoTree();
                slave.showNoTree();
                //--->>>
                Global.mainModule.getUI().getMainWindow().getTestingWindow().ShowNoSapforPackageVersionEtalon();
                Global.mainModule.getUI().getMainWindow().getTestingWindow().ShowNoSapforPackageVersion();
            }
            @Override
            protected void body() throws Exception {
                ForkJoinPool commonPool = ForkJoinPool.commonPool();
                System.out.println("parallel comparison");
                commonPool.submit(() ->
                        package1.package_json.tasks.parallelStream()
                                .forEach(task1 -> {
                                    SapforTask task2 = package2.package_json.getTaskByKey(task1.getUniqueKey());
                                    task1.checkMatch(task2);
                                })
                ).join();
                System.out.println("done");
                package1.package_json.buildComparisonTree(package1);
                package2.package_json.buildComparisonTree(package2);
            }
            @Override
            protected boolean validate() {
                return Log.isEmpty();
            }
            @Override
            protected void showFail() throws Exception {
                showCommonTree();
                slave.showCommonTree();
            }
            @Override
            protected void performDone() throws Exception {
                comparisonMode = true;
                slave.comparisonMode = true;
                //--
            }
            @Override
            protected void showDone() throws Exception {
                showComparisonTree();
                slave.showComparisonTree();
                SynchronizeTrees();
            }
        };
        pass.Do();
    }
    public void SynchronizeTrees() {
        if (slave.Body != null) {
            Body.setSlaveTree(slave.Body);
            slave.treeScroll.getVerticalScrollBar().setModel(treeScroll.getVerticalScrollBar().getModel());
        }
    }
}
