package dev.lions.unionflow.server.service;

import io.quarkus.cache.CacheManager;
import io.quarkus.test.InjectMock;
import io.quarkus.test.junit.QuarkusTest;
import jakarta.inject.Inject;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

import javax.sql.DataSource;
import java.lang.reflect.Method;

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

/**
 * Tests de couverture complémentaires pour SystemConfigService.
 * Couvre la branche formatBytes() avec bytes < 1024.
 */
@QuarkusTest
class SystemConfigServiceCoverageTest {

    @Inject
    SystemConfigService systemConfigService;

    @InjectMock
    CacheManager cacheManager;

    @InjectMock
    DataSource dataSource;

    /**
     * Invoque la méthode privée formatBytes(long) via réflexion.
     */
    private String invokeFormatBytes(long bytes) throws Exception {
        Method method = SystemConfigService.class.getDeclaredMethod("formatBytes", long.class);
        method.setAccessible(true);
        return (String) method.invoke(systemConfigService, bytes);
    }

    @Test
    @DisplayName("formatBytes avec valeur < 1024 retourne suffixe 'B'")
    void formatBytes_lessThan1024_returnsBytes() throws Exception {
        String result = invokeFormatBytes(512L);
        assertThat(result).isEqualTo("512 B");
    }

    @Test
    @DisplayName("formatBytes avec exactement 0 retourne '0 B'")
    void formatBytes_zero_returnsZeroBytes() throws Exception {
        String result = invokeFormatBytes(0L);
        assertThat(result).isEqualTo("0 B");
    }

    @Test
    @DisplayName("formatBytes avec valeur en kilobytes retourne suffixe 'KB'")
    void formatBytes_kilobytes_returnsKB() throws Exception {
        // 2 KB = 2048 bytes
        String result = invokeFormatBytes(2048L);
        assertThat(result).contains("KB");
    }

    @Test
    @DisplayName("formatBytes avec valeur en megabytes retourne suffixe 'MB'")
    void formatBytes_megabytes_returnsMB() throws Exception {
        // 5 MB = 5 * 1024 * 1024 = 5_242_880 bytes
        String result = invokeFormatBytes(5_242_880L);
        assertThat(result).contains("MB");
    }

    @Test
    @DisplayName("formatBytes avec valeur en gigabytes retourne suffixe 'GB'")
    void formatBytes_gigabytes_returnsGB() throws Exception {
        // 1 GB = 1_073_741_824 bytes
        String result = invokeFormatBytes(1_073_741_824L);
        assertThat(result).contains("GB");
    }

    @Test
    @DisplayName("formatBytes avec 1023 retourne '1023 B' (limite < 1024)")
    void formatBytes_exactlyBeforeThreshold_returnsBytes() throws Exception {
        String result = invokeFormatBytes(1023L);
        assertThat(result).isEqualTo("1023 B");
    }
}
