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 org.junit.jupiter.api.Test;

class SimulationProfilerTest {

    @Test
    void recordsCycleModulesEventsRegionsSavesAndBudgetOverruns() {
        SimulationProfiler profiler = new SimulationProfiler();

        profiler.beginCycle();
        profiler.beginModule("soil");
        profiler.endModule("soil");
        profiler.recordEvent();
        profiler.recordRegionUpdated();
        profiler.recordSave();
        profiler.recordBudgetOverrun();
        profiler.endCycle();

        SimulationProfileSnapshot snapshot = profiler.createSnapshot();
        assertTrue(snapshot.totalCycleNanos() >= 0);
        assertTrue(snapshot.moduleTimings().get("soil") >= 0);
        assertEquals(1, snapshot.eventsPublished());
        assertEquals(1, snapshot.regionsUpdated());
        assertEquals(1, snapshot.savesPerformed());
        assertTrue(snapshot.budgetExceeded());
        assertTrue(snapshot.toHumanReadableString().contains("soil"));
    }

    @Test
    void supportsExistingSimulationProfilerAdapterMethods() {
        com.livingworld.core.simulation.SimulationProfiler profiler =
                new SimulationProfiler();

        profiler.startCycle(12);
        profiler.beginModule("water");
        profiler.endModule("water");
        profiler.endCycle(1);
    }

    @Test
    void validatesProfilingLifecycle() {
        SimulationProfiler profiler = new SimulationProfiler();

        assertThrows(IllegalStateException.class, profiler::endCycle);
        profiler.beginCycle();
        assertThrows(IllegalStateException.class, profiler::beginCycle);
        assertThrows(IllegalArgumentException.class, () -> profiler.beginModule(" "));
        assertThrows(IllegalStateException.class, () -> profiler.endModule("soil"));
    }
}
