package cn.novalon.manage.gateway.health;

import io.github.resilience4j.circuitbreaker.CircuitBreaker;
import io.github.resilience4j.circuitbreaker.CircuitBreakerRegistry;
import io.github.resilience4j.ratelimiter.RateLimiterRegistry;
import org.springframework.boot.actuate.health.Health;
import org.springframework.boot.actuate.health.HealthIndicator;
import org.springframework.stereotype.Component;

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

/**
 * 网关健康检查指示器
 * 
 * 文件定义：实现自定义健康检查逻辑，监控网关核心组件状态
 * 涉及业务：网关健康状态监控，包括断路器、限流器等关键组件
 * 
 * 健康检查内容：
 * 1. 断路器状态：检查所有断路器是否处于健康状态
 * 2. 限流器状态：检查限流器是否正常工作
 * 3. 自定义指标：检查网关特定的健康指标
 * 
 * @author 张翔
 * @date 2026-03-26
 */
@Component
public class GatewayHealthIndicator implements HealthIndicator {

    private final CircuitBreakerRegistry circuitBreakerRegistry;
    private final RateLimiterRegistry rateLimiterRegistry;

    public GatewayHealthIndicator(
            CircuitBreakerRegistry circuitBreakerRegistry,
            RateLimiterRegistry rateLimiterRegistry) {
        this.circuitBreakerRegistry = circuitBreakerRegistry;
        this.rateLimiterRegistry = rateLimiterRegistry;
    }

    @Override
    public Health health() {
        Health.Builder builder = Health.up();

        Map<String, Object> details = new HashMap<>();

        checkCircuitBreakers(details);
        checkRateLimiters(details);

        boolean hasUnhealthyComponents = details.values().stream()
                .filter(value -> value instanceof Map)
                .map(value -> (Map<?, ?>) value)
                .flatMap(map -> map.values().stream())
                .filter(value -> value instanceof Map)
                .map(value -> (Map<?, ?>) value)
                .anyMatch(componentDetails -> 
                        componentDetails.containsKey("status") && 
                        "DOWN".equals(componentDetails.get("status")));

        if (hasUnhealthyComponents) {
            builder = Health.down();
        }

        builder.withDetails(details);
        return builder.build();
    }

    private void checkCircuitBreakers(Map<String, Object> details) {
        Map<String, Object> circuitBreakerDetails = new HashMap<>();

        circuitBreakerRegistry.getAllCircuitBreakers().forEach(circuitBreaker -> {
            String name = circuitBreaker.getName();
            CircuitBreaker.State state = circuitBreaker.getState();
            
            Map<String, Object> cbDetails = new HashMap<>();
            cbDetails.put("state", state.name());
            cbDetails.put("status", state == CircuitBreaker.State.OPEN ? "DOWN" : "UP");
            
            circuitBreakerDetails.put(name, cbDetails);
        });

        details.put("circuitBreakers", circuitBreakerDetails);
    }

    private void checkRateLimiters(Map<String, Object> details) {
        Map<String, Object> rateLimiterDetails = new HashMap<>();

        rateLimiterRegistry.getAllRateLimiters().forEach(rateLimiter -> {
            String name = rateLimiter.getName();
            
            Map<String, Object> rlDetails = new HashMap<>();
            rlDetails.put("status", "UP");
            rlDetails.put("availablePermissions", 
                    rateLimiter.getRateLimiterConfig().getLimitForPeriod());
            
            rateLimiterDetails.put(name, rlDetails);
        });

        details.put("rateLimiters", rateLimiterDetails);
    }
}
