package dev.lions.unionflow.server.service;

import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

import io.quarkus.oidc.runtime.OidcJwtCallerPrincipal;
import io.quarkus.security.identity.SecurityIdentity;
import java.lang.reflect.Field;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

/**
 * Test SANS @QuarkusTest pour couvrir la branche OidcJwtCallerPrincipal
 * dans KeycloakService.getRawAccessToken() (ligne 304).
 *
 * <p>Cette branche ne peut pas être couverte dans un @QuarkusTest car @InjectMock
 * injecte un proxy Mockito de JsonWebToken qui n'est pas instanceof OidcJwtCallerPrincipal.
 * Ici on instancie KeycloakService directement et on injecte les fields via réflexion.
 */
class KeycloakServiceOidcBranchTest {

    @Test
    @DisplayName("getRawAccessToken avec OidcJwtCallerPrincipal → retourne le raw token (branche instanceof)")
    void getRawAccessToken_whenOidcJwtCallerPrincipal_returnsRawToken() throws Exception {
        // Créer une instance de KeycloakService sans CDI
        KeycloakService service = new KeycloakService();

        // Mock SecurityIdentity (non-anonymous = authenticated)
        SecurityIdentity si = mock(SecurityIdentity.class);
        when(si.isAnonymous()).thenReturn(false);

        // Mock OidcJwtCallerPrincipal → IS-A JsonWebToken ET OidcJwtCallerPrincipal
        OidcJwtCallerPrincipal oidcPrincipal = mock(OidcJwtCallerPrincipal.class);
        when(oidcPrincipal.getRawToken()).thenReturn("raw-oidc-token");

        // Injecter les champs via réflexion
        Field siField = KeycloakService.class.getDeclaredField("securityIdentity");
        siField.setAccessible(true);
        siField.set(service, si);

        Field jwtField = KeycloakService.class.getDeclaredField("jwt");
        jwtField.setAccessible(true);
        jwtField.set(service, oidcPrincipal);

        // Appeler getRawAccessToken() — doit prendre la branche OidcJwtCallerPrincipal
        String token = service.getRawAccessToken();

        assertThat(token).isEqualTo("raw-oidc-token");
    }
}
