package dev.lions.unionflow.server;

import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

import java.lang.reflect.Field;

import static org.assertj.core.api.Assertions.assertThat;

/**
 * Tests complémentaires pour {@link UnionFlowServerApplication#buildBaseUrl()}.
 *
 * <p>Utilise une sous-classe {@link TestableApp} pour contrôler la valeur de
 * UNIONFLOW_DOMAIN sans manipulation fragile des variables d'environnement.
 */
@DisplayName("UnionFlowServerApplication — buildBaseUrl")
class UnionFlowServerApplicationBuildBaseUrlTest {

    /** Sous-classe permettant de simuler une valeur de UNIONFLOW_DOMAIN sans toucher à l'env. */
    @jakarta.enterprise.inject.Vetoed
    private static class TestableApp extends UnionFlowServerApplication {
        private final String mockDomain;

        TestableApp(String mockDomain) {
            this.mockDomain = mockDomain;
        }

        @Override
        protected String getUnionflowDomain() {
            return mockDomain;
        }
    }

    /** Utilitaire : injecte une valeur dans un champ privé de l'instance via réflexion. */
    private static void setField(Object instance, String fieldName, Object value) throws Exception {
        Field f = UnionFlowServerApplication.class.getDeclaredField(fieldName);
        f.setAccessible(true);
        f.set(instance, value);
    }

    private static UnionFlowServerApplication buildApp(
            String activeProfile, String httpHost, int httpPort, String domain) throws Exception {
        UnionFlowServerApplication app = new TestableApp(domain);
        setField(app, "activeProfile", activeProfile);
        setField(app, "httpHost", httpHost);
        setField(app, "httpPort", httpPort);
        return app;
    }

    @Test
    @DisplayName("buildBaseUrl: profil dev → URL http://localhost:port (branche profil non-prod)")
    void buildBaseUrl_profilDev_retourneUrlLocale() throws Exception {
        UnionFlowServerApplication app = buildApp("dev", "0.0.0.0", 8085, null);
        assertThat(app.buildBaseUrl()).isEqualTo("http://localhost:8085");
    }

    @Test
    @DisplayName("buildBaseUrl: profil test → URL http://localhost:port (branche profil non-prod)")
    void buildBaseUrl_profilTest_retourneUrlLocale() throws Exception {
        UnionFlowServerApplication app = buildApp("test", "0.0.0.0", 9090, null);
        assertThat(app.buildBaseUrl()).isEqualTo("http://localhost:9090");
    }

    @Test
    @DisplayName("buildBaseUrl: httpHost non '0.0.0.0' → utilise httpHost directement (branche ternaire)")
    void buildBaseUrl_httpHostPersonnalise_utilisehttpHostDirectement() throws Exception {
        UnionFlowServerApplication app = buildApp("dev", "192.168.1.100", 8085, null);
        // httpHost != "0.0.0.0" → host = "192.168.1.100" (branche else du ternaire)
        assertThat(app.buildBaseUrl()).isEqualTo("http://192.168.1.100:8085");
    }

    @Test
    @DisplayName("buildBaseUrl: profil prod, domain=null → condition false (A=false) → URL locale")
    void buildBaseUrl_profilProd_sansDomain_retourneUrlLocale() throws Exception {
        // getUnionflowDomain() retourne null → domain != null → false → localhost
        UnionFlowServerApplication app = buildApp("prod", "0.0.0.0", 8085, null);
        assertThat(app.buildBaseUrl()).isEqualTo("http://localhost:8085");
    }

    @Test
    @DisplayName("buildBaseUrl: profil prod avec UNIONFLOW_DOMAIN défini → return 'https://domain'")
    void buildBaseUrl_profilProd_avecDomain_retourneHttps() throws Exception {
        // getUnionflowDomain() retourne "api.lions.dev" → condition true → https://
        UnionFlowServerApplication app = buildApp("prod", "0.0.0.0", 8085, "api.lions.dev");
        assertThat(app.buildBaseUrl()).isEqualTo("https://api.lions.dev");
    }

    @Test
    @DisplayName("buildBaseUrl: profil prod avec UNIONFLOW_DOMAIN vide ('') → URL locale (branche isEmpty()=true)")
    void buildBaseUrl_profilProd_domainVide_retourneUrlLocale() throws Exception {
        // getUnionflowDomain() retourne "" → domain != null (A=true) && !domain.isEmpty() (B=false) → false
        UnionFlowServerApplication app = buildApp("prod", "0.0.0.0", 8085, "");
        assertThat(app.buildBaseUrl()).isEqualTo("http://localhost:8085");
    }
}
