package GlobalData;
import Common.Current;
import Common.Database.DBObject;
import Common.Database.SQLITE.SQLiteDatabase;
import Common.Global;
import GlobalData.Account.Account;
import GlobalData.Account.AccountsDBTable;
import GlobalData.Compiler.CompilersDBTable;
import GlobalData.Credentials.Credentials;
import GlobalData.Credentials.CredentialsDBTable;
import GlobalData.DBLastProject.LastProjectsDBTable;
import GlobalData.DVMParameter.DVMParameterDBTable;
import GlobalData.EnvironmentValue.EnvironmentValuesDBTable;
import GlobalData.FormsParams.FormsDBTable;
import GlobalData.FormsParams.MainFormParamsDBTable;
import GlobalData.Grid.GridsDBTable;
import GlobalData.Machine.MachinesDBTable;
import GlobalData.Makefile.MakefilesDBTable;
import GlobalData.Module.ModulesDBTable;
import GlobalData.RunConfiguration.RunConfigurationsDBTable;
import GlobalData.SapforProfile.SapforProfile;
import GlobalData.SapforProfile.SapforProfilesDBTable;
import GlobalData.SapforProfileSetting.SapforProfileSetting;
import GlobalData.SapforProfileSetting.SapforProfileSettingsDBTable;
import GlobalData.Settings.DBSetting;
import GlobalData.Settings.SettingName;
import GlobalData.Settings.SettingsDBTable;
import GlobalData.Splitter.SplittersDBTable;
import GlobalData.Tasks.CompilationTask.CompilationTasksDBTable;
import GlobalData.Tasks.RunTask.RunTasksDBTable;
import GlobalData.User.UsersDBTable;
import Repository.Component.ComponentType;
import Visual_DVM_2021.PassStats.PassStatsDBTable;
import Visual_DVM_2021.Passes.PassCode_2021;

import java.nio.file.Paths;
import java.util.Date;
import java.util.LinkedHashMap;
public class GlobalDatabase extends SQLiteDatabase {
    //---------СЕАНС----------------------------------------------
    public MachinesDBTable machines;
    public UsersDBTable users;
    public CompilersDBTable compilers;
    public MakefilesDBTable makefiles;
    public ModulesDBTable modules;
    public CompilationTasksDBTable compilationTasks;
    public RunTasksDBTable runTasks;
    public RunConfigurationsDBTable runConfigurations;
    public EnvironmentValuesDBTable environmentValues;
    public DVMParameterDBTable dvmParameters;
    public CredentialsDBTable credentials;
    //----- ДАННЫЕ ВИЗУАЛИЗАТОРА---------------------------------
    public FormsDBTable forms;
    public MainFormParamsDBTable mainFormParams;
    public SettingsDBTable settings;
    public LastProjectsDBTable lastProjects;
    public AccountsDBTable accounts;
    public PassStatsDBTable passStats;
    public SplittersDBTable splitters;
    public GridsDBTable grids;
    //-
    public SapforProfilesDBTable sapforProfiles = null;
    //---------
    public SapforProfileSettingsDBTable sapforProfilesSettings = null;
    //-
    public GlobalDatabase() {
        super(Paths.get(System.getProperty("user.dir"), "Data", Global.properties.GlobalDBName).toFile());
    }
    @Override
    protected void initAllTables() throws Exception {
        addTable(machines = new MachinesDBTable());
        addTable(users = new UsersDBTable());
        addTable(compilers = new CompilersDBTable());
        addTable(makefiles = new MakefilesDBTable());
        addTable(modules = new ModulesDBTable());
        addTable(compilationTasks = new CompilationTasksDBTable());
        addTable(runTasks = new RunTasksDBTable());
        addTable(runConfigurations = new RunConfigurationsDBTable());
        addTable(environmentValues = new EnvironmentValuesDBTable());
        addTable(credentials = new CredentialsDBTable());
        addTable(forms = new FormsDBTable());
        addTable(settings = new SettingsDBTable());
        addTable(mainFormParams = new MainFormParamsDBTable());
        addTable(lastProjects = new LastProjectsDBTable());
        addTable(accounts = new AccountsDBTable());
        addTable(passStats = new PassStatsDBTable());
        addTable(splitters = new SplittersDBTable());
        addTable(dvmParameters = new DVMParameterDBTable());
        addTable(grids = new GridsDBTable());
        addTable(sapforProfiles = new SapforProfilesDBTable());
        addTable(sapforProfilesSettings = new SapforProfileSettingsDBTable());
    }
    //---------------------------------------------------------------------------------
    @Override
    public void Init() throws Exception {
        Current.set(Current.Account,
                accounts.Data.isEmpty() ? Insert(new Account()) :
                        accounts.getFirstRecord()
        );
        Current.set(Current.Credentials,
                credentials.Data.isEmpty() ? Insert(new Credentials()) :
                        credentials.getFirstRecord());
        //настройки компонент
        settings.AddAll();
        runConfigurations.Patch();
    }
    @Override
    public PassCode_2021 getSynchronizePassCode() {
        return null;
    }
    public void SaveCredentials(){
        try {
            Credentials credentials = (Credentials) Current.get(Current.Credentials);
            if (Current.HasMachine())
                credentials.machine_id = Current.getMachine().id;
            if (Current.HasUser())
                credentials.user_id = Current.getUser().id;
            if (Current.HasCompiler())
                credentials.compiler_id = Current.getCompiler().id;
            if (Current.HasMakefile())
                credentials.makefile_id = Current.getMakefile().id;
            if (Current.HasRunConfiguration())
                credentials.runconfiguration_id = Current.getRunConfiguration().id;
            Update(credentials);
        }
        catch (Exception ex){
            ex.printStackTrace();
        }
    }
    public void UpdateCredentials() {
        try {
            Global.db.Update((DBObject) Current.get(Current.Credentials));
        } catch (Exception ex) {
            Global.Log.PrintException(ex);
        }
    }
    //--
    public LinkedHashMap<SettingName, String> getSapforSettingsForProfile() {
        LinkedHashMap<SettingName, String> res = new LinkedHashMap<>();
        for (DBSetting setting : Global.db.settings.getSettingsByOwner(ComponentType.SapforOptions))
            if (setting.Visible)
                res.put(setting.Name, setting.Value);
        return res;
    }
    //проверить, есть ли профиль с таким же набором настроек.
    public SapforProfile checkProfileForCurrentSettings() {
        LinkedHashMap<SettingName, String> current_values = getSapforSettingsForProfile();
        for (SapforProfile profile : sapforProfiles.Data.values()) {
            //--получить все настройки профиля
            LinkedHashMap<SettingName, String> profileValues = new LinkedHashMap<>();
            for (SapforProfileSetting setting : sapforProfilesSettings.Data.values())
                if (setting.sapforprofile_id == profile.id) profileValues.put(setting.name, setting.value);
            //--
            if (current_values.equals(profileValues)) return profile;
        }
        return null;
    }
    public void insertProfileSettings(SapforProfile profile) throws Exception {
        LinkedHashMap<SettingName, String> current_values = getSapforSettingsForProfile();
        for (SettingName name : current_values.keySet()) {
            //--
            SapforProfileSetting sapforProfileSetting = new SapforProfileSetting();
            sapforProfileSetting.name = name;
            sapforProfileSetting.value = current_values.get(name);
            sapforProfileSetting.sapforprofile_id = profile.id;
            //--
            Insert(sapforProfileSetting);
        }
    }
    public void saveCurrentProfile(String name_in) throws Exception {
        if (Global.db.checkProfileForCurrentSettings() == null) {
            SapforProfile profile = new SapforProfile();
            profile.description = name_in;
            profile.creationDate = new Date().getTime();
            Global.db.Insert(profile);
            Global.db.insertProfileSettings(profile);
        }
    }
    public void rewriteProfileByDescription(String description_in) throws Exception {
        SapforProfile old = null;
        //ищем профиль с именем бага
        for (SapforProfile p : Global.db.sapforProfiles.Data.values())
            if (p.description.equalsIgnoreCase(description_in)) {
                old = p;
                break;
            }
        if (old != null) {
            //удалить профиль с именем бага,если есть, чтобы не множить кроликов.
            //при условии что не видно окна профилей!!
            Global.db.Delete(old);
            Global.db.DeleteByFK(old, SapforProfileSetting.class);
        }
        //---
        SapforProfile profile = new SapforProfile();
        profile.description = description_in;
        profile.creationDate = new Date().getTime();
        Global.db.Insert(profile);
        Global.db.insertProfileSettings(profile);
    }
}
