package Repository.Component;
import Common.Constants;
import Common.Database.DBObject;
import Common.Global;
import Common.Utils.Files.VFileChooser;
import Common.Utils.TextLog;
import Common.Utils.Utils;
import Visual_DVM_2021.Passes.PassException;
import Visual_DVM_2021.UI.Interface.Loggable;

import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
public abstract class Component extends DBObject implements Loggable {
    public String date_text = Constants.dateNaN;
    public long version = Constants.Nan;
    public long actual_version = Constants.Nan;
    public long minimal_version = Constants.Nan;
    //--
    public String code = "";
    public String actual_code = "";
    public boolean needs_update_minimal_version = false;
    private ComponentState state;
    public abstract ComponentType getComponentType();
    VFileChooser fileChooser = null; ///для ручной установки.
    public VFileChooser getFileChooser() {
        return (fileChooser == null) ? (fileChooser = new VFileChooser("выбор файла для компонента " +
                Utils.Brackets(getComponentType().getDescription()), Utils.getExtension(getFile())))
                : fileChooser;
    }
    //--
    public String getVersionText() {
        return String.valueOf(version);
    }
    public void CheckIfNeedsUpdateOrPublish() {
        if (actual_version != Constants.Nan) {
            if (version < minimal_version) setState(ComponentState.Old_version);
            else {
                ComponentState new_state =
                        (actual_version > version) ? ComponentState.Needs_update : (
                                (actual_version < version) ? ComponentState.Needs_publish : ComponentState.Actual);
                setState(new_state);
            }
        }
    }
    public void InitialVersionCheck() {
        setState(ComponentState.Undefined);
        if (getFile().exists()) {
            GetVersionInfo();
            if (version == Constants.Nan)
                setState(ComponentState.Unknown_version);
        } else setState(ComponentState.Not_found);
    }
    public boolean CanBeUpdated() {
        return state != ComponentState.Not_found && state != ComponentState.Unknown_version && state != ComponentState.Old_version;
    }
    public void GetVersionInfo() {
    }
    public void unpackActualVersion(String v_string) {
        actual_version = Long.parseLong(v_string);
    }
    public void unpackMinimalVersion(String v_string) {
        minimal_version = Long.parseLong(v_string);
    }
    public void ReplaceOldFile() throws Exception {
        Utils.delete_with_check(getFile());
        System.out.println("old file removed");
        //-скопировать файл
        Files.move(getNewFile().toPath(), getFile().toPath(), StandardCopyOption.REPLACE_EXISTING);
        //удалить новый файл.
        Utils.delete_with_check(getNewFile());
        System.out.println("new file removed");
    }
    public void Update() throws Exception {
        if (!getNewFile().setExecutable(true)) throw new PassException("Не удалось разрешить файл\n" +
                getNewFile() +
                "\nна выполнение");
    }
    @Override
    public boolean isVisible() {
        return true;
    }
    @Override
    public Object getPK() {
        return getComponentType();
    }
    public boolean isValidVersion(TextLog Log, String desc) {
        if (version == Constants.Nan) {
            Log.Writeln_("Не определена версия " + desc + " компонента " + Utils.Brackets(getComponentType().getDescription()));
            return false;
        }
        return true;
    }
    //------------------>>>
    public String getHome() {
        return Global.ComponentsDirectory.getAbsolutePath();
    }
    public String getFileName() {
        return "";
    }
    public String getNewFileName() {
        return "";
    }
    public String getBackUpFileName() {
        return getComponentType().toString() + "_" + version;
    }
    public File getFile() {
        return Paths.get(getHome(), getFileName()).toFile();
    }
    public File getNewFile() {
        return Paths.get(getHome(), getNewFileName()).toFile();
    }
    public File getBackUpFile() {
        return Paths.get(Global.BackUpsDirectory.getAbsolutePath(), getBackUpFileName()).toFile();
    }
    public ComponentState getState() {
        return state;
    }
    public void setState(ComponentState state_in) {
        state = state_in;
    }
    public String getAssemblyCommand() {
        return "";
    }
    public File getAssemblyFile() {
        return null;
    }
    @Override
    public String getLogHomePath() {
        return Global.ComponentsDirectory.getAbsolutePath();
    }
    @Override
    public String getLogName() {
        return getComponentType().toString();
    }
    public boolean isNecessary() {
        return true;
    }
}