package net.northking.cctp.daemon.service;

import net.northking.cctp.daemon.entity.DaemonEngineInfo;
import net.northking.cctp.daemon.entity.DaemonStatus;
import net.northking.cctp.daemon.entity.ScriptEngineVersion;
import net.northking.cctp.daemon.repository.DaemonEngineInfoRepository;
import net.northking.cctp.se.dto.ScriptEngineInfo;
import org.springframework.stereotype.Service;
import org.springframework.data.domain.Sort;

import java.io.File;
import java.util.List;
import java.util.Optional;

@Service
public class DaemonServiceImpl implements DaemonService {
    private static DaemonEngineInfo DAEMON_ENGINE_INFO;

    private final DaemonEngineInfoRepository repository;

    public DaemonServiceImpl(DaemonEngineInfoRepository repository) {
        this.repository = repository;
    }

    @Override
    public void updateLastVersion(ScriptEngineVersion lastVersion) {
        if (!lastVersion.getVersion().equals(DAEMON_ENGINE_INFO.getVersion())
                && !lastVersion.getVersion().equals(DAEMON_ENGINE_INFO.getUpgradeVersion())
                && DaemonStatus.INIT.name().equals(DAEMON_ENGINE_INFO.getStatus())) {
            DAEMON_ENGINE_INFO.setUpgradeVersion(lastVersion.getVersion());
            DAEMON_ENGINE_INFO.setDownloadUrl(lastVersion.getDownloadUrl());
            DAEMON_ENGINE_INFO.setStatus(DaemonStatus.WAIT.name());
            repository.save(DAEMON_ENGINE_INFO);
        }
    }

    @Override
    public DaemonEngineInfo getInfo() {
        if (DAEMON_ENGINE_INFO == null) {
            Sort.Order order = new Sort.Order(Sort.Direction.DESC, "upgradeVersion");
            List<DaemonEngineInfo> list = repository.findAll(Sort.by(order));
            if (list != null && list.size() > 0) {
                DAEMON_ENGINE_INFO = list.get(0);
            }
        }
        return DAEMON_ENGINE_INFO;
    }

    @Override
    public void updateInitVersion(ScriptEngineVersion intVersion) {
        DAEMON_ENGINE_INFO = new DaemonEngineInfo();
        DAEMON_ENGINE_INFO.setVersion(intVersion.getVersion());
        DAEMON_ENGINE_INFO.setUpgradeVersion(intVersion.getVersion());
        DAEMON_ENGINE_INFO.setDownloadUrl(intVersion.getDownloadUrl());
        DAEMON_ENGINE_INFO.setStatus(DaemonStatus.WAIT.name());
        repository.save(DAEMON_ENGINE_INFO);
    }


    @Override
    public String getPatchDirectory() {
        return DAEMON_ENGINE_INFO.getPatchDirectory();
    }

    @Override
    public void updateEngineInfo(ScriptEngineInfo scriptEngineInfo) {
        if (DAEMON_ENGINE_INFO == null) {
            Optional<DaemonEngineInfo> optional = repository.findById(scriptEngineInfo.getVersion());
            if (optional.isPresent()) {
                DAEMON_ENGINE_INFO = optional.get();
            } else {
                DAEMON_ENGINE_INFO = new DaemonEngineInfo();
                DAEMON_ENGINE_INFO.setVersion(scriptEngineInfo.getVersion());
                DAEMON_ENGINE_INFO.setStatus(DaemonStatus.INIT.name());
            }
        } else {
            if (scriptEngineInfo.getVersion().equals(DAEMON_ENGINE_INFO.getVersion())
                    || !DaemonStatus.INIT.name().equals(DAEMON_ENGINE_INFO.getStatus())) {
                // 增加校验在版本更新途中，不更新当前数据库版本记录
                // TODO 更新引擎的信息
            } else {
                DAEMON_ENGINE_INFO = new DaemonEngineInfo();
                DAEMON_ENGINE_INFO.setVersion(scriptEngineInfo.getVersion());
                DAEMON_ENGINE_INFO.setStatus(DaemonStatus.INIT.name());
            }
        }
        repository.save(DAEMON_ENGINE_INFO);
    }

    public void upgradeCompleted() {
        DAEMON_ENGINE_INFO.setStatus(DaemonStatus.FINISH.name());
        repository.save(DAEMON_ENGINE_INFO);
    }

    @Override
    public String getDownloadUrl() {
        return DAEMON_ENGINE_INFO.getDownloadUrl();
    }

    @Override
    public void downloadCompleted(File file) {
        DAEMON_ENGINE_INFO.setPatchZipFile(file.getAbsolutePath());
        DAEMON_ENGINE_INFO.setStatus(DaemonStatus.PREPARED_UNZIP.name());
        repository.save(DAEMON_ENGINE_INFO);
    }

    @Override
    public String getUnZipFile() {
        return DAEMON_ENGINE_INFO.getPatchZipFile();
    }

    @Override
    public void unZipCompleted(String unZipDir) {
        DAEMON_ENGINE_INFO.setPatchDirectory(unZipDir);
        DAEMON_ENGINE_INFO.setStatus(DaemonStatus.PREPARED_UPGRADE.name());
        repository.save(DAEMON_ENGINE_INFO);
    }


    @Override
    public void restartEngineFinish() {
        if (DAEMON_ENGINE_INFO != null) {
            DAEMON_ENGINE_INFO.setStatus(DaemonStatus.INIT.name());
            repository.save(DAEMON_ENGINE_INFO);
        }
    }

    @Override
    public boolean preparedLoadLastVersion() {
        return DAEMON_ENGINE_INFO != null && DaemonStatus.INIT.name().equals(DAEMON_ENGINE_INFO.getStatus());
    }

    @Override
    public boolean preparedDownload() {
        return DAEMON_ENGINE_INFO != null && DaemonStatus.PREPARED_DOWNLOAD.name().equals(DAEMON_ENGINE_INFO.getStatus());
    }

    @Override
    public boolean preparedUnZip() {
        return DAEMON_ENGINE_INFO != null && DaemonStatus.PREPARED_UNZIP.name().equals(DAEMON_ENGINE_INFO.getStatus());
    }

    @Override
    public boolean preparedUpgradeEngine() {
        return DAEMON_ENGINE_INFO != null && DaemonStatus.PREPARED_UPGRADE.name().equals(DAEMON_ENGINE_INFO.getStatus());
    }

    public boolean preparedWaitEngine() {
        return DAEMON_ENGINE_INFO != null && DaemonStatus.WAIT.name().equals(DAEMON_ENGINE_INFO.getStatus());
    }


    @Override
    public boolean startCheck() {
        return DAEMON_ENGINE_INFO == null || (DaemonStatus.INIT.name().equals(DAEMON_ENGINE_INFO.getStatus())
                || DaemonStatus.FINISH.name().equals(DAEMON_ENGINE_INFO.getStatus()));
    }


    @Override
    public void updateToDownload() {
        DAEMON_ENGINE_INFO.setStatus(DaemonStatus.PREPARED_DOWNLOAD.name());
        repository.save(DAEMON_ENGINE_INFO);
    }
}

