package _VisualDVM.TestingSystem.SAPFOR.SapforPackage;
import Common.CommonConstants;
import _VisualDVM.Current;
import Common.Database.Objects.DBObject;
import _VisualDVM.Global;
import _VisualDVM.ServerObjectsCache.ConfigurationCache;
import _VisualDVM.ServerObjectsCache.VisualCaches;
import Common.Utils.TextLog;
import _VisualDVM.Utils;
import _VisualDVM.GlobalData.Account.Account;
import _VisualDVM.GlobalData.Tasks.TaskState;
import _VisualDVM.TestingSystem.Common.TasksPackageState;
import _VisualDVM.TestingSystem.Common.Test.Test;
import _VisualDVM.TestingSystem.Common.TestingPackage.TestingPackage;
import _VisualDVM.TestingSystem.SAPFOR.Json.SapforPackage_json;
import _VisualDVM.TestingSystem.SAPFOR.SapforConfiguration.SapforConfiguration;
import _VisualDVM.TestingSystem.SAPFOR.SapforTask.SapforTask;
import _VisualDVM.TestingSystem.SAPFOR.ServerSapfor.ServerSapfor;

import java.io.File;
import java.util.LinkedHashMap;
import java.util.Vector;
public class SapforPackage extends TestingPackage<SapforPackage_json> {
    public int sapforId = CommonConstants.Nan; // так как сапфор на машине.
    //--------------
    public SapforPackage() {
    }
    public SapforPackage(SapforPackage sapforPackage) {
        SynchronizeFields(sapforPackage);
    }
    @Override
    public void SynchronizeFields(DBObject src) {
        super.SynchronizeFields(src);
        SapforPackage p = (SapforPackage) src;
        sapforId = p.sapforId;
    }
    @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 boolean isVisible() {
        return (!SapforPackageDBTable.filterMyOnly || Global.mainModule.getAccount().email.equals(sender_address)) &&
                (!SapforPackageDBTable.filterActive || state.isActive())
                ;
    }
    //---------
    //конструктор. если 0 задач по итогу,значит пакет не запускаем вообще, и смотрим журнал.
    //Запрещено выполнять на нитях, так как прямой доступ к бд.
    public SapforPackage(Account 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;
        //проверка исходных данных тестов и групп
        LinkedHashMap<String, Test> testsByDescriptions = new LinkedHashMap<>();
        //--
        kernels = 1;
        for (SapforConfiguration configuration : configurations) {
            kernels = Math.max(configuration.kernels, kernels);
            configuration.validate(Log);
            //-
            ConfigurationCache cache = (ConfigurationCache) VisualCaches.GetCache(configuration);
            //--
            for (Test test : cache.getTests()) {
                String l_description = test.description.toLowerCase();
                if (testsByDescriptions.containsKey(l_description)) {
                    Log.Writeln_("В пакет не могут входить тесты с одинаковыми именами (без учета регистра):" + test.description.toLowerCase());
                    valid = false;
                } else {
                    testsByDescriptions.put(l_description, test);
                }
            }
        }
        valid = Log.isEmpty();
        //формирование задач.
        if (valid) {
            package_json = new SapforPackage_json(serverSapfor, testsByDescriptions, configurations, kernels);
            tasksCount = package_json.tasks.size();
            saveConfigurationsAsJson(configurations);
        }
    }
    @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++;
        }
        state = (bad > 0) ? TasksPackageState.DoneWithErrors : TasksPackageState.Done;
        double percent = ( ((double)(good))/tasksCount)*100.0;
        description = "Выполнено на "+((int)percent)+"%\n"+
                "Всего задач: "+tasksCount+", из них с ошибками "+bad;
    }
}
