package space.animefu.starfallhaven;

import org.junit.Test;
import java.nio.file.Files;
import java.nio.file.Paths;
import static org.junit.Assert.*;

public class V4ChroniclePersistenceTest {
    @Test public void chronicleAndAcceptedGrokNarrativeRoundTripByteStable()throws Exception{
        GameWorld world=new GameWorld(4040);world.day=9;world.food=60;ChronicleDirector.Outcome outcome=world.runChronicle();
        assertTrue(world.acceptChronicleNarrative(outcome.selectionSeed,"Signal over the Haven","Grok framed the accepted local event without changing it.","mysterious"));
        int wood=world.wood,food=world.food,tension=world.chronicleTension;
        byte[] encoded=GameWorldSave.encode(world);GameWorld restored=GameWorldSave.decode(encoded);ChronicleHistory.Entry entry=restored.latestChronicle();
        assertEquals(4,GameWorldSave.VERSION);assertNotNull(entry);assertEquals("GROK",entry.source);assertEquals("Signal over the Haven",entry.headline);assertEquals("mysterious",entry.tone);
        assertEquals(wood,restored.wood);assertEquals(food,restored.food);assertEquals(tension,restored.chronicleTension);assertEquals(world.chronicleNextDay,restored.chronicleNextDay);
        assertArrayEquals(encoded,GameWorldSave.encode(restored));
    }

    @Test public void frozenV3MigratesWithFutureLocalIncidentSchedule()throws Exception{
        byte[] bytes=Files.readAllBytes(Paths.get("src/test/resources/saves/v3-qualified.bin"));GameWorld restored=GameWorldSave.decode(bytes);
        assertEquals(0,restored.chronicleHistory.size());assertEquals(20,restored.chronicleTension);assertEquals(0,restored.chronicleThreat);assertTrue(restored.chronicleNextDay>restored.day);
    }

    @Test public void dayTransitionSchedulesIncidentWithoutNarrationSideEffects(){
        GameWorld world=new GameWorld(77);world.confirmLandingSite();world.chronicleNextDay=2;world.day=1;world.timeOfDay=.9999f;
        world.update(.1f);assertEquals(2,world.day);assertEquals(1,world.chronicleHistory.size());ChronicleHistory.Entry entry=world.latestChronicle();
        int wood=world.wood,food=world.food,size=world.chronicleHistory.size();
        assertTrue(world.acceptChronicleNarrative(entry.selectionSeed,"Reframed","Only prose changes.","quiet"));
        assertEquals(size,world.chronicleHistory.size());assertEquals(wood,world.wood);assertEquals(food,world.food);
    }

    @Test public void narrationCanRebindExactPersistedEventAfterSeedBoundary()throws Exception{
        GameWorld world=new GameWorld(8181);world.day=6;ChronicleDirector.Outcome outcome=world.runChronicle();ChronicleHistory.Entry event=world.latestChronicle();
        GameWorld restored=GameWorldSave.decode(GameWorldSave.encode(world));
        assertTrue(restored.acceptChronicleNarrative(event.day,event.incidentId,Long.MIN_VALUE,"Bound Chronicle","Matching prose only.","hopeful"));
        assertEquals("GROK",restored.latestChronicle().source);assertEquals(outcome.incident.id,restored.latestChronicle().incidentId);
    }
}
