package space.animefu.starfallhaven;

import org.junit.Test;
import static org.junit.Assert.*;

public class GameWorldPersistenceTest {
    @Test public void saveRoundTripPreservesCompleteMutableState() throws Exception {
        GameWorld original=new GameWorld(84621L);
        original.wood=77; original.stone=66; original.food=55; original.crystal=44;
        original.day=4; original.timeOfDay=.73f; original.speed=2; original.paused=true;
        original.setTool(GameWorld.Tool.WALL); original.walls[3][5]=true;
        original.tiles[7][9]=GameWorld.Tile.CRYSTAL;
        GameWorld.Colonist c=original.colonists.get(0);
        c.x=8.25f;c.y=9.75f;c.health=72;c.hunger=63;c.energy=51;c.tx=7;c.ty=9;c.work=1.2f;
        original.enemies.add(GameWorld.enemyForTest(12.5f,13.5f,19));
        original.setBondForTest(68,4.5f);

        byte[] encoded=GameWorldSave.encode(original);
        GameWorld restored=GameWorldSave.decode(encoded);

        assertEquals(original.wood,restored.wood); assertEquals(original.stone,restored.stone);
        assertEquals(original.food,restored.food); assertEquals(original.crystal,restored.crystal);
        assertEquals(original.day,restored.day); assertEquals(original.timeOfDay,restored.timeOfDay,0f);
        assertEquals(original.speed,restored.speed,0f); assertEquals(original.paused,restored.paused);
        assertEquals(original.tool,restored.tool); assertTrue(restored.walls[3][5]);
        assertEquals(GameWorld.Tile.CRYSTAL,restored.tiles[7][9]);
        GameWorld.Colonist r=restored.colonists.get(0);
        assertEquals(c.name,r.name);assertEquals(c.x,r.x,0f);assertEquals(c.health,r.health,0f);
        assertEquals(c.tx,r.tx);assertEquals(c.work,r.work,0f);
        assertEquals(1,restored.enemies.size());assertEquals(19,restored.enemies.get(0).health,0f);
        assertEquals(68,restored.bondCharge,0f);assertEquals(4.5f,restored.bondActiveSeconds,0f);
        assertArrayEquals("encoding a restored world must be stable",encoded,GameWorldSave.encode(restored));
    }

    @Test public void corruptOrUnsupportedSaveIsRejected() throws Exception {
        byte[] bytes=GameWorldSave.encode(new GameWorld(1)); bytes[0]^=1;
        try { GameWorldSave.decode(bytes); fail("corrupt save accepted"); }
        catch (GameWorldSave.SaveException expected) { assertTrue(expected.getMessage().length()>0); }
    }
}
