package cn.reghao.bnt.web.devops.app.service.webhook;

import cn.reghao.bnt.web.admin.service.NotifyService;
import cn.reghao.bnt.web.admin.service.notifier.ding.DingMsg;
import cn.reghao.bnt.web.devops.app.db.query.AppBuildQuery;
import cn.reghao.bnt.web.devops.app.model.po.config.AppConfig;
import cn.reghao.bnt.web.devops.app.service.bd.BuildApp;
import cn.reghao.bnt.web.devops.app.service.webhook.event.*;
import cn.reghao.jutil.jdk.serializer.JsonConverter;
import cn.reghao.jutil.web.ServletUtil;
import com.google.gson.JsonObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author reghao
 * @date 2022-05-10 08:22:15
 */
@Slf4j
@Service
public class WebhookService {
    private final AppBuildQuery appBuildQuery;
    private final BuildApp buildApp;
    private final NotifyService notifyService;
    private final Map<String, PushEvent> map = new HashMap<>();

    public WebhookService(AppBuildQuery appBuildQuery, BuildApp buildApp,
                          NotifyService notifyService, List<PushEvent> list) {
        this.appBuildQuery = appBuildQuery;
        this.buildApp = buildApp;
        this.notifyService = notifyService;
        initPushEvent(list);
    }

    private void initPushEvent(List<PushEvent> list) {
        list.forEach(pushEvent -> map.put(pushEvent.getClass().getSimpleName(), pushEvent));
    }

    public void handle(String json) throws Exception {
        JsonObject jsonObject = JsonConverter.jsonToJsonElement(json).getAsJsonObject();
        BuildParam buildParam;
        if (ServletUtil.getHeader("X-Gogs-Event") != null) {
            buildParam = map.get(GogsPushEvent.class.getSimpleName()).handle(jsonObject);
        } else if (ServletUtil.getHeader("X-Codeup-Event") != null) {
            buildParam = map.get(CodeupPushEvent.class.getSimpleName()).handle(jsonObject);
        } else if (ServletUtil.getHeader("X-GitHub-Event") != null) {
            buildParam = map.get(GithubPushEvent.class.getSimpleName()).handle(jsonObject);
        } else {
            return;
        }
        buildAndDeploy(buildParam);
    }

    private void buildAndDeploy(BuildParam buildParam) throws Exception {
        AppConfig appConfig = appBuildQuery.getByRepoAndBranch(buildParam.getRepo(), buildParam.getBranch());
        if (appConfig != null && "uat".equals(appConfig.getEnv())) {
            String appId = appConfig.getAppId();
            notifyEvt(appId, buildParam.getBuildBy());

            boolean deploy = !"devops-mgr".equals(appId) && !"devops-agent".equals(appId);
            String buildBy = buildParam.getBuildBy();
            buildApp.buildAndDeploy(appId, deploy);
        }
    }

    private void notifyEvt(String appId, String buildBy) {
        String msg = String.format("%s 触发 %s 自动 CI/CD...", buildBy, appId);
        DingMsg dingMsg = new DingMsg(msg);
        notifyService.notify(dingMsg);
    }
}
