package com.zioinfo.kintex.auth;

import com.zioinfo.kintex.tenant.TenantContext;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.security.Keys;
import org.junit.jupiter.api.Test;

import javax.crypto.SecretKey;
import java.nio.charset.StandardCharsets;
import java.util.Map;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;

/**
 * 테넌트 표준화(2026-07-12) 하위호환 단위테스트 — 표준 코드 대문자('KINTEX') 정규화가
 * 레거시 소문자 tid('kintex')·미지정 토큰을 계속 통과시키는지 검증한다.
 */
class JwtServiceTenantTest {

    private static final String SECRET = "kintex-test-secret-key-0123456789-abcdef"; // >= 32 bytes

    private JwtService newService() {
        AuthProperties props = new AuthProperties();
        props.setJwtSecret(SECRET);
        props.setAccessTokenTtlSeconds(3600);
        return new JwtService(props);
    }

    /** tid 미지정 발급 → 검증 시 기준 테넌트 'KINTEX'로 복원. */
    @Test
    void issuesDefaultTenantAsUppercase() {
        JwtService jwt = newService();
        String token = jwt.issue("u1", "사용자", Map.of(), false);
        KintexPrincipal p = jwt.verify(token);
        assertEquals("KINTEX", p.tenantId());
    }

    /** 소문자 'kintex'로 발급해도 검증 결과는 표준 대문자 'KINTEX'. */
    @Test
    void normalizesLowercaseTenantOnIssue() {
        JwtService jwt = newService();
        String token = jwt.issue("u1", "사용자", Map.of(), false, "MANAGER", "kintex");
        KintexPrincipal p = jwt.verify(token);
        assertEquals("KINTEX", p.tenantId());
    }

    /** 레거시(기존 발급) 소문자 tid='kintex' 토큰도 검증 시 'KINTEX'로 정규화 복원(하위호환). */
    @Test
    void verifiesLegacyLowercaseTidToken() {
        JwtService jwt = newService();
        SecretKey key = Keys.hmacShaKeyFor(SECRET.getBytes(StandardCharsets.UTF_8));
        String legacy = Jwts.builder()
                .subject("u-legacy")
                .claim("name", "레거시")
                .claim("roles", Map.of())
                .claim("hm", false)
                .claim("tid", "kintex") // 표준화 이전 발급 토큰 모사
                .signWith(key)
                .compact();
        KintexPrincipal p = jwt.verify(legacy);
        assertEquals("KINTEX", p.tenantId());
    }

    /** TenantContext.normalize 계약 — trim+대문자, null/공백 → null. */
    @Test
    void normalizeContract() {
        assertEquals("KINTEX", TenantContext.normalize("kintex"));
        assertEquals("KINTEX", TenantContext.normalize("  KINTEX  "));
        assertEquals("COEX", TenantContext.normalize("coex"));
        assertNull(TenantContext.normalize(null));
        assertNull(TenantContext.normalize("  "));
        assertEquals("KINTEX", TenantContext.currentTenantId()); // 미설정 폴백
    }
}
