package com.livingworld.debug;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;

import java.util.LinkedHashMap;
import java.util.Map;
import org.junit.jupiter.api.Test;

class SimulationProfileSnapshotTest {

    @Test
    void defensivelyCopiesAndLocksModuleTimings() {
        Map<String, Long> timings = new LinkedHashMap<>();
        timings.put("ecology", 2_000_000L);

        SimulationProfileSnapshot snapshot =
                new SimulationProfileSnapshot(3_000_000L, timings, 2, 3, 1, false);
        timings.put("settlements", 1_000_000L);

        assertEquals(Map.of("ecology", 2_000_000L), snapshot.moduleTimings());
        assertThrows(
                UnsupportedOperationException.class,
                () -> snapshot.moduleTimings().put("weather", 500_000L));
    }

    @Test
    void rejectsInvalidValues() {
        assertThrows(
                IllegalArgumentException.class,
                () -> new SimulationProfileSnapshot(-1, Map.of(), 0, 0, 0, false));
        assertThrows(
                IllegalArgumentException.class,
                () -> new SimulationProfileSnapshot(0, Map.of("", 1L), 0, 0, 0, false));
        assertThrows(
                IllegalArgumentException.class,
                () -> new SimulationProfileSnapshot(0, Map.of("test", -1L), 0, 0, 0, false));
    }

    @Test
    void formatsMeasurementsForDebugOutput() {
        SimulationProfileSnapshot snapshot = new SimulationProfileSnapshot(
                3_000_000L, Map.of("test", 2_000_000L), 2, 3, 1, true);

        String output = snapshot.toHumanReadableString();

        assertTrue(output.contains("cycle=3.0ms"));
        assertTrue(output.contains("test=2.0ms"));
        assertTrue(output.contains("events=2"));
        assertTrue(output.contains("budgetExceeded=true"));
    }
}
