using NUnit.Framework;
using ProjectM.Simulation;
using UnityEngine;
namespace ProjectM.Tests
{
///
/// Tests the SaveData v2 structure-persistence schema (M7): a player-built structure set + the flat machine-I/O
/// table round-trip through JsonUtility with fields intact; the REMAINING-ticks cooldown survives an epoch reset
/// (RemainingTicks/RestoreNextTick); and a save JSON lacking the v2 arrays deserializes without throwing (degrades
/// to no structures). The deeper instantiate-from-catalog restore is covered by the Play-mode validation pass.
///
public class AutomationSaveRoundTripTests
{
[Test]
public void StructuresAndIo_RoundTrip_PreservesFields()
{
var data = new SaveData
{
GoalCharge = 3,
GoalTarget = 10,
Structures = new[]
{
new StructureSave { Type = StructureType.Harvester, CellX = 4, CellZ = -2, RemainingTicks = 12 },
new StructureSave { Type = StructureType.Conveyor, CellX = 5, CellZ = -2, Direction = 2, RemainingTicks = 3, ConveyorResId = ResourceId.Ore, ConveyorCount = 1 },
new StructureSave { Type = StructureType.Fabricator, CellX = 6, CellZ = -2, RemainingTicks = 40 },
},
StructureIo = new[]
{
new StructureIoRow { StructureIndex = 0, Slot = 1, ResourceId = ResourceId.Ore, Count = 7 },
new StructureIoRow { StructureIndex = 2, Slot = 0, ResourceId = ResourceId.Ore, Count = 5 },
},
};
var back = JsonUtility.FromJson(JsonUtility.ToJson(data));
Assert.AreEqual(SaveData.CurrentVersion, back.Version);
Assert.AreEqual(3, back.Structures.Length);
Assert.AreEqual(StructureType.Conveyor, back.Structures[1].Type);
Assert.AreEqual(2, back.Structures[1].Direction);
Assert.AreEqual(ResourceId.Ore, back.Structures[1].ConveyorResId);
Assert.AreEqual(1, back.Structures[1].ConveyorCount);
Assert.AreEqual(12u, back.Structures[0].RemainingTicks);
Assert.AreEqual(2, back.StructureIo.Length);
Assert.AreEqual(2, back.StructureIo[1].StructureIndex);
Assert.AreEqual(0, back.StructureIo[1].Slot);
Assert.AreEqual(5, back.StructureIo[1].Count);
}
[Test]
public void RemainingTicks_RestoreNextTick_PreservesCooldownGap_AcrossEpochs()
{
uint saveNow = 5000u, savedNext = 5037u;
uint remaining = ProductionMath.RemainingTicks(savedNext, saveNow);
Assert.AreEqual(37u, remaining);
uint restoreNow = 11u;
uint restoredNext = ProductionMath.RestoreNextTick(restoreNow, remaining);
Assert.AreEqual(48u, restoredNext);
}
[Test]
public void Save_Lacking_V2_Arrays_DeserializesWithoutThrowing()
{
SaveData back = null;
Assert.DoesNotThrow(() => back = JsonUtility.FromJson("{\"Version\":2,\"GoalCharge\":1,\"GoalTarget\":10}"));
Assert.IsNotNull(back);
Assert.IsTrue(back.Structures == null || back.Structures.Length == 0);
}
}
}