package dev.lions.unionflow.server.entity;

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

import java.lang.reflect.Method;
import java.util.UUID;

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

@DisplayName("ConfigurationWave")
class ConfigurationWaveTest {

    @Test
    @DisplayName("getters/setters")
    void gettersSetters() {
        ConfigurationWave c = new ConfigurationWave();
        c.setCle("wave.api.url");
        c.setValeur("https://api.wave.com");
        c.setDescription("URL API Wave");
        c.setTypeValeur("STRING");
        c.setEnvironnement("PRODUCTION");

        assertThat(c.getCle()).isEqualTo("wave.api.url");
        assertThat(c.getValeur()).isEqualTo("https://api.wave.com");
        assertThat(c.getDescription()).isEqualTo("URL API Wave");
        assertThat(c.getTypeValeur()).isEqualTo("STRING");
        assertThat(c.getEnvironnement()).isEqualTo("PRODUCTION");
    }

    @Test
    @DisplayName("isEncryptee true quand typeValeur ENCRYPTED")
    void isEncryptee_true() {
        ConfigurationWave c = new ConfigurationWave();
        c.setCle("x");
        c.setTypeValeur("ENCRYPTED");
        assertThat(c.isEncryptee()).isTrue();
    }

    @Test
    @DisplayName("isEncryptee false sinon")
    void isEncryptee_false() {
        ConfigurationWave c = new ConfigurationWave();
        c.setCle("x");
        c.setTypeValeur("STRING");
        assertThat(c.isEncryptee()).isFalse();
    }

    @Test
    @DisplayName("onCreate initialise typeValeur et environnement si null")
    void onCreate_initialiseChamps() throws Exception {
        ConfigurationWave c = new ConfigurationWave();
        c.setCle("k");
        c.setTypeValeur(null);
        c.setEnvironnement(null);
        Method onCreate = ConfigurationWave.class.getDeclaredMethod("onCreate");
        onCreate.setAccessible(true);
        onCreate.invoke(c);
        assertThat(c.getTypeValeur()).isEqualTo("STRING");
        assertThat(c.getEnvironnement()).isEqualTo("COMMON");
    }

    @Test
    @DisplayName("onCreate initialise typeValeur et environnement si vide")
    void onCreate_initialiseChamps_empty() throws Exception {
        ConfigurationWave c = new ConfigurationWave();
        c.setCle("k2");
        c.setTypeValeur("");
        c.setEnvironnement("");
        Method onCreate = ConfigurationWave.class.getDeclaredMethod("onCreate");
        onCreate.setAccessible(true);
        onCreate.invoke(c);
        assertThat(c.getTypeValeur()).isEqualTo("STRING");
        assertThat(c.getEnvironnement()).isEqualTo("COMMON");
    }

    @Test
    @DisplayName("onCreate: typeValeur et environnement déjà renseignés → non écrasés")
    void onCreate_existingValues_notOverwritten() throws Exception {
        ConfigurationWave c = new ConfigurationWave();
        c.setCle("k3");
        c.setTypeValeur("NUMBER");
        c.setEnvironnement("PRODUCTION");
        Method onCreate = ConfigurationWave.class.getDeclaredMethod("onCreate");
        onCreate.setAccessible(true);
        onCreate.invoke(c);
        assertThat(c.getTypeValeur()).isEqualTo("NUMBER");
        assertThat(c.getEnvironnement()).isEqualTo("PRODUCTION");
    }

    @Test
    @DisplayName("isEncryptee: false si typeValeur null")
    void isEncryptee_nullTypeValeur_returnsFalse() {
        ConfigurationWave c = new ConfigurationWave();
        c.setCle("x");
        c.setTypeValeur(null);
        assertThat(c.isEncryptee()).isFalse();
    }

    @Test
    @DisplayName("equals et hashCode")
    void equalsHashCode() {
        UUID id = UUID.randomUUID();
        ConfigurationWave a = new ConfigurationWave();
        a.setId(id);
        a.setCle("k1");
        ConfigurationWave b = new ConfigurationWave();
        b.setId(id);
        b.setCle("k1");
        assertThat(a).isEqualTo(b);
        assertThat(a.hashCode()).isEqualTo(b.hashCode());
    }

    @Test
    @DisplayName("toString non null")
    void toString_nonNull() {
        ConfigurationWave c = new ConfigurationWave();
        c.setCle("x");
        assertThat(c.toString()).isNotNull().isNotEmpty();
    }
}
