package cn.reghao.autodop.dmaster.app.service.rpc;

import cn.reghao.autodop.common.http.DefaultWebRequest;
import cn.reghao.autodop.common.http.WebRequest;
import cn.reghao.autodop.common.msg.rpc.dto.app.AppStatus;
import cn.reghao.autodop.common.msg.rpc.dto.app.DeployResult;
import cn.reghao.autodop.dmaster.app.db.query.config.AppConfigQuery;
import cn.reghao.autodop.dmaster.app.db.repository.AppDeployingRepository;
import cn.reghao.autodop.dmaster.app.db.repository.AppRunningRepository;
import cn.reghao.autodop.dmaster.app.db.repository.log.BuildLogRepository;
import cn.reghao.autodop.dmaster.app.db.repository.log.DeployLogRepository;
import cn.reghao.autodop.dmaster.app.model.po.AppDeploying;
import cn.reghao.autodop.dmaster.app.model.po.AppRunning;
import cn.reghao.autodop.dmaster.app.model.po.config.AppConfig;
import cn.reghao.autodop.dmaster.app.model.po.log.BuildLog;
import cn.reghao.autodop.dmaster.app.model.po.log.DeployLog;
import cn.reghao.autodop.dmaster.app.service.bd.DeployNotifyMsg;
import cn.reghao.autodop.dmaster.notification.model.po.NotifyGroup;
import cn.reghao.autodop.dmaster.notification.model.po.NotifyType;
import cn.reghao.autodop.dmaster.notification.service.NotifyService;
import cn.reghao.autodop.dmaster.notification.service.notifier.ding.DingMsg;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Optional;

/**
 * @author reghao
 * @date 2021-07-01 20:15:57
 */
@Service
public class AppRpcClazzResultHandlerImpl implements AppRpcClazzResultHandler {
    private AppRunningRepository runningRepository;
    private NotifyService notifyService;
    private WebRequest webRequest;
    private BuildLogRepository buildLogRepository;
    private DeployLogRepository deployLogRepository;
    private AppDeployingRepository deployingRepository;
    private AppConfigQuery appConfigQuery;

    public AppRpcClazzResultHandlerImpl(AppRunningRepository runningRepository,
                                        NotifyService notifyService,
                                        BuildLogRepository buildLogRepository,
                                        DeployLogRepository deployLogRepository,
                                        AppDeployingRepository deployingRepository,
                                        AppConfigQuery appConfigQuery) {
        this.runningRepository = runningRepository;
        this.notifyService = notifyService;
        this.webRequest = new DefaultWebRequest();
        this.buildLogRepository = buildLogRepository;
        this.deployLogRepository = deployLogRepository;
        this.deployingRepository = deployingRepository;
        this.appConfigQuery = appConfigQuery;
    }

    @Override
    public void deployResult(DeployResult deployResult) {
        DeployLog deployLog = DeployLog.from(deployResult);
        deployLogRepository.save(deployLog);

        String buildId = deployResult.getBuildLogId();
        // TODO 部署时将 BuildLog 放到缓存中
        Optional<BuildLog> optional = buildLogRepository.findById(buildId);
        if (optional.isPresent()) {
            BuildLog buildLog = optional.get();
            updateDeployingStatus(buildLog, deployResult);
            updateRunningStatus(buildLog, deployResult);
            deployNotify(buildLog, deployResult);
        }
    }

    private void updateDeployingStatus(BuildLog buildLog, DeployResult deployResult) {
        String appId = buildLog.getAppId();
        String machineId = deployResult.getMachineId();
        AppDeploying deploying = deployingRepository.findByAppIdAndMachineId(appId, machineId);
        if (deploying != null) {
            deploying.update(buildLog, deployResult);
            deployingRepository.save(deploying);
        }
    }

    private void updateRunningStatus(BuildLog buildLog, DeployResult deployResult) {
        String appId = buildLog.getAppId();
        String machineId = deployResult.getMachineId();
        AppRunning running = runningRepository.findByAppIdAndMachineId(appId, machineId);
        if (running != null) {
            running.update(buildLog, deployResult.getAppStatus());
            runningRepository.save(running);
        }
    }

    private void deployNotify(BuildLog buildLog, DeployResult deployResult) {
        AppConfig app = appConfigQuery.findByAppId(buildLog.getAppId());
        List<NotifyGroup> notifyGroups = app.getNotifyGroups();
        notifyGroups.forEach(notifyGroup -> {
            String notifyType = notifyGroup.getNotifyType();
            switch (NotifyType.valueOf(notifyType)) {
                case ding:
                    DingMsg dingMsg = new DeployNotifyMsg(buildLog, deployResult).dingMsg();
                    notifyService.notify(notifyGroup, dingMsg);
                    break;
                case email:
                    break;
                case sms:
                    break;
                default:
            }
        });
    }

    @Override
    public void statusResult(AppStatus appStatus) {
        String appId = appStatus.getAppId();
        String machineId = appStatus.getMachineId();
        AppRunning appRunning = runningRepository.findByAppIdAndMachineId(appId, machineId);
        if (appRunning != null) {
            appRunning.update(appStatus);
            runningRepository.save(appRunning);
        }
    }
}
