package cn.novalon.gym.manage.gateway.health;

import io.github.resilience4j.circuitbreaker.CircuitBreakerConfig;
import io.github.resilience4j.circuitbreaker.CircuitBreakerRegistry;
import io.github.resilience4j.ratelimiter.RateLimiterConfig;
import io.github.resilience4j.ratelimiter.RateLimiterRegistry;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.boot.actuate.health.Health;
import org.springframework.boot.actuate.health.Status;

import java.time.Duration;

import static org.junit.jupiter.api.Assertions.*;

/**
 * GatewayHealthIndicator单元测试
 * 
 * 文件定义：测试网关健康检查指示器的核心功能
 * 涉及业务：断路器健康检查、限流器健康检查
 * 
 * @author 张翔
 * @date 2026-03-26
 */
@ExtendWith(MockitoExtension.class)
class GatewayHealthIndicatorTest {

    private CircuitBreakerRegistry circuitBreakerRegistry;
    private RateLimiterRegistry rateLimiterRegistry;
    private GatewayHealthIndicator healthIndicator;

    @BeforeEach
    void setUp() {
        CircuitBreakerConfig cbConfig = CircuitBreakerConfig.custom()
                .failureRateThreshold(50)
                .slidingWindowSize(100)
                .minimumNumberOfCalls(10)
                .waitDurationInOpenState(Duration.ofSeconds(10))
                .build();

        RateLimiterConfig rlConfig = RateLimiterConfig.custom()
                .limitForPeriod(100)
                .limitRefreshPeriod(Duration.ofSeconds(1))
                .build();

        circuitBreakerRegistry = CircuitBreakerRegistry.of(cbConfig);
        rateLimiterRegistry = RateLimiterRegistry.of(rlConfig);

        healthIndicator = new GatewayHealthIndicator(circuitBreakerRegistry, rateLimiterRegistry);
    }

    @Test
    void testHealth_WhenAllComponentsHealthy_ShouldReturnUp() {
        circuitBreakerRegistry.circuitBreaker("test-cb");
        rateLimiterRegistry.rateLimiter("test-rl");

        Health health = healthIndicator.health();

        assertEquals(Status.UP, health.getStatus());
        assertTrue(health.getDetails().containsKey("circuitBreakers"));
        assertTrue(health.getDetails().containsKey("rateLimiters"));
    }

    @Test
    void testHealth_WhenNoComponents_ShouldReturnUp() {
        Health health = healthIndicator.health();

        assertEquals(Status.UP, health.getStatus());
    }

    @Test
    void testHealth_ShouldIncludeComponentDetails() {
        circuitBreakerRegistry.circuitBreaker("gateway");
        rateLimiterRegistry.rateLimiter("gateway");

        Health health = healthIndicator.health();

        assertTrue(health.getDetails().containsKey("circuitBreakers"));
        assertTrue(health.getDetails().containsKey("rateLimiters"));
    }
}
