package SapforTestingSystem.SapforTask;
import Common.Constants;
import Common.Current;
import Common.Database.DBObject;
import Common.Utils.Utils;
import GlobalData.Tasks.TaskState;
import SapforTestingSystem.Json.SapforVersion_json;
import Visual_DVM_2021.Passes.PassCode_2021;
import com.google.gson.annotations.Expose;
import com.sun.org.glassfish.gmbal.Description;
import org.apache.commons.io.FileUtils;

import java.io.File;
import java.nio.charset.Charset;
import java.util.List;
import java.util.Vector;
public class SapforTask extends DBObject {
    //------------------------------------>>
    @Description("PRIMARY KEY, UNIQUE")
    @Expose
    public long id = Constants.Nan;
    @Description("DEFAULT '-1'")
    @Expose
    public String sapfor_configuration_id = "";
    @Description("DEFAULT ''")
    public String sapfortaskspackage_id = "";
    //------------------------------------->>
    @Description("DEFAULT ''")
    @Expose
    public String test_description = "";
    @Description("DEFAULT ''")
    @Expose
    public String group_description = "";
    @Description("DEFAULT ''")
    @Expose
    public String flags = "";
    @Description("DEFAULT ''")
    @Expose
    public String codes = "";
    @Expose
    public TaskState state = TaskState.Inactive;
    //в json не выносить. это только для БД.
    @Description("DEFAULT ''")
    public String files = "";
    @Description("DEFAULT ''")
    public String versionsDescription = "";
    //------
    //-----------
    @Description("IGNORE")
    @Expose
    public List<String> filesList = new Vector<>(); //файлы проекта.Брать из коррекции стиля кода. есть первой версия
    //-------------------------------------->>
    @Description("IGNORE")
    @Expose
    public Vector<SapforVersion_json> versions = new Vector<>();
    //----------
    @Description("IGNORE")
    @Expose
    public Vector<SapforVersion_json> variants = new Vector<>();
    //-----------
    public SapforTask() {
    }
    public void Reset() {
        state = TaskState.Inactive;
        filesList.clear();
        versions.clear();
        variants.clear();
    }
    public SapforTask(SapforTask src) {
        this.SynchronizeFields(src);
    }
    @Override
    public Object getPK() {
        return id;
    }
    @Override
    public void SynchronizeFields(DBObject object) {
        super.SynchronizeFields(object);
        SapforTask t = (SapforTask) object;
        id = t.id;
        sapfor_configuration_id = t.sapfor_configuration_id;
        sapfortaskspackage_id = t.sapfortaskspackage_id;
        //-
        test_description = t.test_description;
        group_description = t.group_description;
        versionsDescription = t.versionsDescription;
        //--
        files = t.files;
        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_2021.CreateParallelVariants.getDescription()));
        }
        return String.join("→", versionsLines);
    }
    public static boolean compareVersionsFiles(SapforVersion_json version1, SapforVersion_json version2, List<String> files) throws Exception {
        for (String fileName : files) {
            File file1 = new File(version1.version, fileName);
            if (!file1.exists()) return false;
            File file2 = new File(version2.version, fileName);
            if (!file2.exists()) return false;
            String text1 = FileUtils.readFileToString(file1, Charset.defaultCharset());
            String text2 = FileUtils.readFileToString(file2, Charset.defaultCharset());
            if (!text1.equals(text2))
                return false;
        }
        return true;
    }
    //должны совпасть им теста, флаги, и коды
    public boolean isComparable(SapforTask task) throws Exception {
        return test_description.equalsIgnoreCase(task.test_description) &&
                flags.equalsIgnoreCase(task.flags) &&
                codes.equalsIgnoreCase(task.codes);
    }
    public boolean Compare(SapforTask task, Vector<String> comparisonLog) throws Exception {
        //1. сравнить списки файлов. без учета порядка.
        if (filesList.size() != task.filesList.size())
            return false;
        for (String file1 : filesList) {
            if (!task.filesList.contains(file1)) {
                return false;
            }
        }
        //2. сравнить состояния.
        if (!state.equals(task.state))
            return false;
        //3. сравнить цепочки версий (?)
        if (!getVersionsChain().equalsIgnoreCase(task.getVersionsChain()))
            return false;
        //4. сравнить версии. уже знаем что порядок преобразований идентичен и набор файлов одинаков.
        // первая всегда исходная. поэтому не берется.
        for (int i = 1; i < versions.size(); ++i) {
            SapforVersion_json version1 = versions.get(i);
            SapforVersion_json version2 = task.versions.get(i);
            //--
            if (!compareVersionsFiles(version1, version2, filesList)) return false;
        }
        return false;
    }
    @Override
    public boolean isVisible() {
        return Current.HasSapforTasksPackage()&&Current.getSapforTasksPackage().id.equals(this.sapfortaskspackage_id);
    }
}
