package dev.lions.unionflow.server.client;

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 io.quarkus.test.InjectMock;
import io.quarkus.test.junit.QuarkusTest;
import jakarta.inject.Inject;
import jakarta.ws.rs.core.MultivaluedHashMap;
import jakarta.ws.rs.core.MultivaluedMap;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

/**
 * Tests pour {@link OidcTokenPropagationHeadersFactory#update} — branche OidcJwtCallerPrincipal
 * (lignes 50-60).
 *
 * <p>Les tests dans {@link OidcTokenPropagationHeadersFactoryTest} utilisent {@code @TestSecurity}
 * dont le principal N'EST PAS un {@link OidcJwtCallerPrincipal} → lignes 50-60 jamais atteintes.
 * Ce test mock {@code SecurityIdentity} pour retourner un mock de {@link OidcJwtCallerPrincipal},
 * couvrant les 2 sous-branches (token valide et token blank).
 */
@QuarkusTest
@DisplayName("OidcTokenPropagationHeadersFactory — branche OidcJwtCallerPrincipal (lignes 50-60)")
class OidcTokenPropagationHeadersFactoryOidcTest {

    @Inject
    OidcTokenPropagationHeadersFactory factory;

    @InjectMock
    SecurityIdentity securityIdentity;

    // =========================================================================
    // Cas 1 : OidcJwtCallerPrincipal avec token valide → propagation (lignes 50-57)
    // =========================================================================

    @Test
    @DisplayName("update avec OidcJwtCallerPrincipal et token valide — couvre lignes 50-57")
    void update_withOidcPrincipalAndValidToken_propagatesToken() {
        OidcJwtCallerPrincipal mockPrincipal = mock(OidcJwtCallerPrincipal.class);
        when(mockPrincipal.getRawToken()).thenReturn("eyJhbGciOiJSUzI1NiJ9.valid-token");

        when(securityIdentity.isAnonymous()).thenReturn(false);
        when(securityIdentity.getPrincipal()).thenReturn(mockPrincipal);

        MultivaluedMap<String, String> incoming = new MultivaluedHashMap<>();
        MultivaluedMap<String, String> outgoing = new MultivaluedHashMap<>();

        MultivaluedMap<String, String> result = factory.update(incoming, outgoing);

        assertThat(result.getFirst("Authorization"))
                .isEqualTo("Bearer eyJhbGciOiJSUzI1NiJ9.valid-token");
    }

    // =========================================================================
    // Cas 2 : OidcJwtCallerPrincipal avec token blank → warn (ligne 59)
    // =========================================================================

    @Test
    @DisplayName("update avec OidcJwtCallerPrincipal et token blank — couvre ligne 59 (warn + pas de propagation)")
    void update_withOidcPrincipalAndBlankToken_noTokenPropagated() {
        OidcJwtCallerPrincipal mockPrincipal = mock(OidcJwtCallerPrincipal.class);
        when(mockPrincipal.getRawToken()).thenReturn("   "); // blank token → branche else ligne 58-60

        when(securityIdentity.isAnonymous()).thenReturn(false);
        when(securityIdentity.getPrincipal()).thenReturn(mockPrincipal);

        MultivaluedMap<String, String> incoming = new MultivaluedHashMap<>();
        MultivaluedMap<String, String> outgoing = new MultivaluedHashMap<>();

        MultivaluedMap<String, String> result = factory.update(incoming, outgoing);

        assertThat(result.containsKey("Authorization")).isFalse();
    }
}
