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

import io.github.resilience4j.circuitbreaker.CircuitBreaker;
import io.github.resilience4j.circuitbreaker.CircuitBreakerRegistry;
import io.github.resilience4j.retry.Retry;
import io.github.resilience4j.retry.RetryRegistry;
import io.github.resilience4j.timelimiter.TimeLimiter;
import io.github.resilience4j.timelimiter.TimeLimiterRegistry;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.test.util.ReflectionTestUtils;

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

/**
 * ResilienceConfig单元测试
 * 
 * 文件定义：测试Resilience4j配置类的核心功能
 * 涉及业务：断路器、重试、超时配置
 * 
 * @author 张翔
 * @date 2026-03-26
 */
@ExtendWith(MockitoExtension.class)
class ResilienceConfigTest {

    @InjectMocks
    private ResilienceConfig resilienceConfig;

    @Test
    void testCircuitBreakerRegistry_ShouldCreateRegistry() {
        ReflectionTestUtils.setField(resilienceConfig, "circuitBreakerEnabled", true);
        ReflectionTestUtils.setField(resilienceConfig, "failureRateThreshold", 50.0f);
        ReflectionTestUtils.setField(resilienceConfig, "slowCallRateThreshold", 100.0f);
        ReflectionTestUtils.setField(resilienceConfig, "slowCallDurationThreshold", java.time.Duration.ofSeconds(2));
        ReflectionTestUtils.setField(resilienceConfig, "permittedNumberOfCallsInHalfOpenState", 10);
        ReflectionTestUtils.setField(resilienceConfig, "slidingWindowType", "COUNT_BASED");
        ReflectionTestUtils.setField(resilienceConfig, "slidingWindowSize", 100);
        ReflectionTestUtils.setField(resilienceConfig, "minimumNumberOfCalls", 10);
        ReflectionTestUtils.setField(resilienceConfig, "waitDurationInOpenState", java.time.Duration.ofSeconds(10));

        CircuitBreakerRegistry registry = resilienceConfig.circuitBreakerRegistry();

        assertNotNull(registry);
        assertNotNull(registry.getConfiguration("default"));
    }

    @Test
    void testGatewayCircuitBreaker_ShouldCreateCircuitBreaker() {
        ReflectionTestUtils.setField(resilienceConfig, "circuitBreakerEnabled", true);
        ReflectionTestUtils.setField(resilienceConfig, "failureRateThreshold", 50.0f);
        ReflectionTestUtils.setField(resilienceConfig, "slowCallRateThreshold", 100.0f);
        ReflectionTestUtils.setField(resilienceConfig, "slowCallDurationThreshold", java.time.Duration.ofSeconds(2));
        ReflectionTestUtils.setField(resilienceConfig, "permittedNumberOfCallsInHalfOpenState", 10);
        ReflectionTestUtils.setField(resilienceConfig, "slidingWindowType", "COUNT_BASED");
        ReflectionTestUtils.setField(resilienceConfig, "slidingWindowSize", 100);
        ReflectionTestUtils.setField(resilienceConfig, "minimumNumberOfCalls", 10);
        ReflectionTestUtils.setField(resilienceConfig, "waitDurationInOpenState", java.time.Duration.ofSeconds(10));

        CircuitBreakerRegistry registry = resilienceConfig.circuitBreakerRegistry();
        CircuitBreaker circuitBreaker = resilienceConfig.gatewayCircuitBreaker(registry);

        assertNotNull(circuitBreaker);
        assertEquals("gateway", circuitBreaker.getName());
    }

    @Test
    void testRetryRegistry_ShouldCreateRegistry() {
        ReflectionTestUtils.setField(resilienceConfig, "retryEnabled", true);
        ReflectionTestUtils.setField(resilienceConfig, "retryMaxAttempts", 3);
        ReflectionTestUtils.setField(resilienceConfig, "retryWaitDuration", java.time.Duration.ofMillis(500));

        RetryRegistry registry = resilienceConfig.retryRegistry();

        assertNotNull(registry);
        assertNotNull(registry.getConfiguration("default"));
    }

    @Test
    void testGatewayRetry_ShouldCreateRetry() {
        ReflectionTestUtils.setField(resilienceConfig, "retryEnabled", true);
        ReflectionTestUtils.setField(resilienceConfig, "retryMaxAttempts", 3);
        ReflectionTestUtils.setField(resilienceConfig, "retryWaitDuration", java.time.Duration.ofMillis(500));

        RetryRegistry registry = resilienceConfig.retryRegistry();
        Retry retry = resilienceConfig.gatewayRetry(registry);

        assertNotNull(retry);
        assertEquals("gateway", retry.getName());
    }

    @Test
    void testTimeLimiterRegistry_ShouldCreateRegistry() {
        ReflectionTestUtils.setField(resilienceConfig, "timeoutEnabled", true);
        ReflectionTestUtils.setField(resilienceConfig, "timeoutDuration", java.time.Duration.ofSeconds(3));

        TimeLimiterRegistry registry = resilienceConfig.timeLimiterRegistry();

        assertNotNull(registry);
        assertNotNull(registry.getConfiguration("default"));
    }

    @Test
    void testGatewayTimeLimiter_ShouldCreateTimeLimiter() {
        ReflectionTestUtils.setField(resilienceConfig, "timeoutEnabled", true);
        ReflectionTestUtils.setField(resilienceConfig, "timeoutDuration", java.time.Duration.ofSeconds(3));

        TimeLimiterRegistry registry = resilienceConfig.timeLimiterRegistry();
        TimeLimiter timeLimiter = resilienceConfig.gatewayTimeLimiter(registry);

        assertNotNull(timeLimiter);
        assertEquals("gateway", timeLimiter.getName());
    }
}
