package _VisualDVM.TestingSystem.SAPFOR.SapforPackage;
import Common.CommonConstants;
import Common.Database.Objects.DBObject;
import Common.Utils.TextLog;
import Common.Utils.Utils_;
import _VisualDVM.ComponentsServer.UserAccount.UserAccount;
import _VisualDVM.Global;
import _VisualDVM.GlobalData.Tasks.TaskState;
import _VisualDVM.TestingSystem.Common.Configuration.Configuration;
import _VisualDVM.TestingSystem.Common.TasksPackageState;
import _VisualDVM.TestingSystem.Common.TestingPackage.TestingPackage;
import _VisualDVM.TestingSystem.SAPFOR.Json.SapforPackage_json;
import _VisualDVM.TestingSystem.SAPFOR.Json.SapforVersion_json;
import _VisualDVM.TestingSystem.SAPFOR.SapforConfiguration.SapforConfiguration;
import _VisualDVM.TestingSystem.SAPFOR.SapforPackageConfiguration.SapforPackageConfiguration;
import _VisualDVM.TestingSystem.SAPFOR.SapforTask.SapforTask;
import _VisualDVM.TestingSystem.SAPFOR.ServerSapfor.ServerSapfor;
import com.sun.org.glassfish.gmbal.Description;

import java.io.File;
import java.util.Vector;
public class SapforPackage extends TestingPackage<SapforPackage_json> {
    public int sapforId = CommonConstants.Nan; // так как сапфор на машине.
    //--
    @Description("DEFAULT -1")
    public int ethalon_id = CommonConstants.Nan;
    @Description("DEFAULT 0")
    public int mismatchesCount = 0; //различия с эталоном
    //--
    @Description("IGNORE")
    public Vector<SapforPackageConfiguration> configurations = null;
    public SapforPackage() {
    }
    public SapforPackage(SapforPackage sapforPackage) {
        SynchronizeFields(sapforPackage);
    }
    //---------
    //конструктор. если 0 задач по итогу,значит пакет не запускаем вообще, и смотрим журнал.
    //Запрещено выполнять на нитях, так как прямой доступ к бд.
    public SapforPackage(UserAccount account, ServerSapfor serverSapfor, Vector<SapforConfiguration> configurations,
                         int neeedsEmail_in,
                         TextLog Log) throws Exception {
        id = CommonConstants.Nan;
        sender_name = account.name;
        sender_address = account.email;
        //-
        sapforId = serverSapfor.id;
        //-
        drv = serverSapfor.call_command;
        version = serverSapfor.version;
        ///-------------------------------
        needsEmail = neeedsEmail_in;
        //-
        state = TasksPackageState.Queued;
        //--
        boolean valid = true;
        //проверка исходных данных тестов и групп
        //--
        kernels = 1;
        for (SapforConfiguration configuration : configurations) {
            kernels = Math.max(configuration.kernels, kernels);
            configuration.validate(Log);
            //-
        }
        valid = Log.isEmpty();
        //формирование задач.
        if (valid) {
            //тесты в рамках конфиги уникальны значит пересечения по папкам уже не будет.
            package_json = new SapforPackage_json(serverSapfor, configurations, kernels);
            tasksCount = package_json.tasks.size();
            saveConfigurations(configurations);
            if (configurations.size() == 1 && configurations.get(0).ethalon_id != CommonConstants.Nan) {
                ethalon_id = configurations.get(0).ethalon_id;
            }
        }
    }
    @Override
    public void SynchronizeFields(DBObject src) {
        super.SynchronizeFields(src);
        SapforPackage p = (SapforPackage) src;
        sapforId = p.sapforId;
        ethalon_id = p.ethalon_id;
        mismatchesCount = p.mismatchesCount;
    }
    @Override
    public Class getJsonClass() {
        return SapforPackage_json.class;
    }
    @Override
    public File getHomeDirectory() {
        return Global.SapforPackagesDirectory;
    }
    //--
    public void init() throws Exception {
        for (SapforTask task : package_json.tasks)
            task.sapfortaskspackage_id = id;
        Utils_.CheckAndCleanDirectory(getLocalWorkspace());
        saveJson();
        package_json = null; // объект больше не нужен.
    }
    @Override
    public void checkFinishState() throws Exception {
        readJson();
        int good = 0;
        int bad = 0;
        for (SapforTask task : package_json.tasks) {
            if (!task.state.equals(TaskState.Done))
                bad++;
            else good++;
            //--
            Vector<SapforVersion_json> all_versions = new Vector<>();
            all_versions.addAll(task.versions);
            all_versions.addAll(task.variants);
            for (SapforVersion_json version_json : all_versions) {
                File configurationRoot = Utils_.getFile(
                        getLocalWorkspace().getAbsolutePath(),
                        String.valueOf(task.set_id),
                        String.valueOf(task.sapfor_configuration_id));
                version_json.getFilesAndCheckState(configurationRoot);
            }
            //--
        }
        saveJson();
        state = (bad > 0) ? TasksPackageState.DoneWithErrors : TasksPackageState.Done;
        double percent = (((double) (good)) / tasksCount) * 100.0;
        description = "Выполнено на " + ((int) percent) + "%\n" +
                "Всего задач: " + tasksCount + ", из них с ошибками " + bad;
        doneTasksCount = good;
    }
    public boolean canCompare(SapforPackage package2, TextLog log) {
        if (package_json.tasks.size() != package2.package_json.tasks.size()) {
            log.Writeln_("Количество задач в пакетах не совпадает!");
            return false;
        }
        for (SapforTask task : package_json.tasks) {
            if (!package2.package_json.containsKey(task.getUniqueKey())) {
                log.Writeln_("Задача эталона " + task.getUniqueKey() + "не найдена в сравниваемом пакете!");
            }
        }
        return log.isEmpty();
    }
    @Override
    public void saveConfigurations(Vector<? extends Configuration> configurations_in) {
        configurations = new Vector<>();
        for (Configuration configuration : configurations_in) {
            configurations.add(new SapforPackageConfiguration((SapforConfiguration) configuration));
        }
    }
}
