/* (C) 2024 YiRing, Inc. */
package com.yiring.common.utils;

import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.spring.SpringUtil;
import cn.hutool.http.HttpUtil;
import com.yiring.common.config.UptimeConfig;
import java.util.Objects;
import lombok.Getter;
import lombok.experimental.UtilityClass;
import lombok.extern.slf4j.Slf4j;

/**
 * @author Jim
 */
@SuppressWarnings("unused")
@Slf4j
@UtilityClass
public class Uptime {

    static String UPTIME_DOMAIN;

    static {
        UptimeConfig config = SpringUtil.getBean(UptimeConfig.class);
        UPTIME_DOMAIN = config.getDomain();
    }

    /**
     * 默认的通知方法
     * eg: <a href="https://uptime.yiring.com">${uptime.domain}</a>
     *
     * @param key    key
     * @param status 状态
     * @param msg    信息
     */
    public void notice(String key, Status status, String msg) {
        notice(UPTIME_DOMAIN, key, status, msg, null);
    }

    /**
     * 默认的通知方法
     * eg: <a href="https://uptime.yiring.com">${uptime.domain}</a>
     *
     * @param key    key
     * @param status 状态
     * @param msg    信息
     * @param ping   Push ping
     */
    public void notice(String key, Status status, String msg, Long ping) {
        if (StrUtil.isBlank(UPTIME_DOMAIN)) {
            throw new RuntimeException("please set ${uptime.domain} value in application config file.");
        }

        notice(UPTIME_DOMAIN, key, status, msg, ping);
    }

    /**
     * 通过 Push 方式通知 Uptime Kuma 健康指标检测平台
     *
     * @param domain Uptime Kuma 的 domain 地址
     * @param key    Push key
     * @param status Push status
     * @param msg    Push message
     * @param ping   Push ping
     */
    private void notice(String domain, String key, Status status, String msg, Long ping) {
        String url = "{}/api/push/{}?status={}&ping={}&msg={}";
        String message = url;

        try {
            // 读取配置文件中的 uptime.domain 覆盖默认配置
            if (!Objects.equals(domain, UPTIME_DOMAIN) && StrUtil.isNotEmpty(UPTIME_DOMAIN)) {
                domain = UPTIME_DOMAIN;
            }

            message = StrUtil.format(message, domain, key, status.getValue(), ping, "***");
            HttpUtil.get(StrUtil.format(url, domain, key, status.getValue(), ping, msg));
        } catch (Exception e) {
            log.error("[Uptime] notice failure: {}", e.getMessage(), e);
        } finally {
            log.info("[Uptime] notice URL: {}", message);
        }
    }

    @Getter
    public enum Status {
        UP("up"),
        DOWN("down");

        final String value;

        Status(String value) {
            this.value = value;
        }
    }
}
