package _VisualDVM.ComponentsServer.Component;
import Common.CommonConstants;
import Common.Database.Objects.DBObject;
import Common.Passes.PassException;
import Common.Utils.Loggable;
import Common.Utils.TextLog;
import Common.Utils.Utils_;
import Common.Visual.Windows.Dialog.VFileChooser;
import _VisualDVM.Constants;
import _VisualDVM.Global;

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 = CommonConstants.Nan;
    public long actual_version = CommonConstants.Nan;
    public long minimal_version = CommonConstants.Nan;
    //--
    public String code = "";
    public String actual_code = "";
    VFileChooser fileChooser = null; ///для ручной установки.
    private ComponentState state;
    public abstract ComponentType getComponentType();
    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 != CommonConstants.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 == CommonConstants.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_.forceDeleteWithCheck(getFile());
        //-скопировать файл
        Files.move(getNewFile().toPath(), getFile().toPath(), StandardCopyOption.REPLACE_EXISTING);
        //удалить новый файл.
        Utils_.forceDeleteWithCheck(getNewFile());
    }
    public void Update() throws Exception {
        if (!getNewFile().setExecutable(true)) throw new PassException("Не удалось разрешить файл\n" +
                getNewFile() +
                "\nна выполнение");
    }
    @Override
    public Object getPK() {
        return getComponentType();
    }
    public boolean isValidVersion(TextLog Log, String desc) {
        if (version == CommonConstants.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;
    }
}