package com.zioinfo.kintex.config;

import com.zioinfo.kintex.auth.AuthProperties;
import com.zioinfo.kintex.security.SecurityPolicyProperties;
import org.junit.jupiter.api.Test;
import org.springframework.mock.env.MockEnvironment;

import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertThrows;

/**
 * B12 — 운영 시크릿 fail-fast 검증기 단위테스트.
 * 시크릿 값 자체는 예외 메시지에 담기지 않음(항목명·조치만)을 함께 확인한다.
 */
class SecretStartupValidatorTest {

    private AuthProperties auth(String secret) {
        AuthProperties p = new AuthProperties();
        p.setJwtSecret(secret);
        return p;
    }

    private SecurityPolicyProperties security(String otpKey) {
        SecurityPolicyProperties p = new SecurityPolicyProperties();
        p.getOtp().setEncKey(otpKey);
        return p;
    }

    @Test
    void prodFailsFastOnDevJwtFallback() {
        MockEnvironment env = new MockEnvironment().withProperty("kintex.security.enforce-secrets", "true");
        SecretStartupValidator v = new SecretStartupValidator(
                env, auth("CHANGE_ME_DEV_ONLY_kintex_local_secret_key_min_32_bytes"),
                security("base64key32byteslongxxxxxxxxxxxxx"));
        IllegalStateException ex = assertThrows(IllegalStateException.class, v::afterPropertiesSet);
        // 시크릿 값이 메시지에 노출되지 않아야 함(항목명만).
        org.junit.jupiter.api.Assertions.assertFalse(ex.getMessage().contains("CHANGE_ME_DEV_ONLY_kintex"));
    }

    @Test
    void prodFailsFastOnMissingOtpKey() {
        MockEnvironment env = new MockEnvironment().withProperty("kintex.security.enforce-secrets", "true");
        SecretStartupValidator v = new SecretStartupValidator(
                env, auth("a-strong-production-secret-of-at-least-32-bytes!!"), security(""));
        assertThrows(IllegalStateException.class, v::afterPropertiesSet);
    }

    @Test
    void prodPassesWithStrongSecrets() {
        MockEnvironment env = new MockEnvironment().withProperty("kintex.security.enforce-secrets", "true");
        SecretStartupValidator v = new SecretStartupValidator(
                env, auth("a-strong-production-secret-of-at-least-32-bytes!!"),
                security("base64key32byteslongxxxxxxxxxxxxx"));
        assertDoesNotThrow(v::afterPropertiesSet);
    }

    @Test
    void devOnlyWarnsNeverThrows() {
        MockEnvironment env = new MockEnvironment(); // no prod profile, no enforce
        SecretStartupValidator v = new SecretStartupValidator(
                env, auth("CHANGE_ME_DEV_ONLY_kintex_local_secret_key_min_32_bytes"), security(""));
        assertDoesNotThrow(v::afterPropertiesSet);
    }
}
