using NUnit.Framework;
using ProjectM.Simulation;
using Unity.Entities;
using UnityEngine;
namespace ProjectM.Tests
{
///
/// Pure tests for the save FOUNDATION: the JSON schema round-trips (JsonUtility), version handling is safe,
/// and the born-correct ledger apply () the server spawn system uses to
/// overwrite a director's StorageEntry buffer from a staged PendingSave.
///
public class SavePersistenceTests
{
[Test]
public void SaveData_Json_RoundTrip_PreservesFields()
{
var data = new SaveData
{
GoalCharge = 42,
GoalTarget = 10,
Ledger = new[]
{
new LedgerRow { ItemId = 1, Count = 5 },
new LedgerRow { ItemId = 2, Count = 9 },
},
SavedAtMs = 1234567890123L,
};
var json = JsonUtility.ToJson(data);
var back = JsonUtility.FromJson(json);
Assert.AreEqual(SaveData.CurrentVersion, back.Version);
Assert.AreEqual(42, back.GoalCharge);
Assert.AreEqual(10, back.GoalTarget);
Assert.AreEqual(2, back.Ledger.Length);
Assert.AreEqual(1, back.Ledger[0].ItemId);
Assert.AreEqual(5, back.Ledger[0].Count);
Assert.AreEqual(2, back.Ledger[1].ItemId);
Assert.AreEqual(9, back.Ledger[1].Count);
Assert.AreEqual(1234567890123L, back.SavedAtMs);
}
[Test]
public void SaveData_EmptyJson_DoesNotThrow_And_EmptyLedgerRoundTrips()
{
Assert.DoesNotThrow(() => JsonUtility.FromJson("{}"));
var empty = new SaveData { GoalCharge = 0, GoalTarget = 10 };
var back = JsonUtility.FromJson(JsonUtility.ToJson(empty));
Assert.IsNotNull(back.Ledger);
Assert.AreEqual(0, back.Ledger.Length);
}
[Test]
public void SaveData_OldVersion_IsDetectable()
{
// A stale-version blob round-trips with its Version intact, so SaveService.Load rejects it (-> New Game).
var old = new SaveData { Version = 0, GoalCharge = 7 };
var back = JsonUtility.FromJson(JsonUtility.ToJson(old));
Assert.AreEqual(0, back.Version);
Assert.AreNotEqual(SaveData.CurrentVersion, back.Version);
}
[Test]
public void WriteLedger_Overwrites_Destination_From_Staged_Rows()
{
using var world = new World("SaveApplyTest");
var em = world.EntityManager;
var e = em.CreateEntity();
em.AddBuffer(e);
em.AddBuffer(e);
var src = em.GetBuffer(e);
src.Add(new PendingSaveLedgerRow { ItemId = 3, Count = 7 });
src.Add(new PendingSaveLedgerRow { ItemId = 5, Count = 12 });
var dest = em.GetBuffer(e);
dest.Add(new StorageEntry { ItemId = 99, Count = 1 }); // pre-existing junk that must be cleared
SaveApply.WriteLedger(em.GetBuffer(e), em.GetBuffer(e));
var result = em.GetBuffer(e);
Assert.AreEqual(2, result.Length);
Assert.AreEqual(3, result[0].ItemId);
Assert.AreEqual(7, result[0].Count);
Assert.AreEqual(5, result[1].ItemId);
Assert.AreEqual(12, result[1].Count);
}
[Test]
public void WriteLedger_EmptySource_ClearsDestination()
{
using var world = new World("SaveApplyEmptyTest");
var em = world.EntityManager;
var e = em.CreateEntity();
em.AddBuffer(e);
em.AddBuffer(e);
var dest = em.GetBuffer(e);
dest.Add(new StorageEntry { ItemId = 1, Count = 1 });
SaveApply.WriteLedger(em.GetBuffer(e), em.GetBuffer(e));
Assert.AreEqual(0, em.GetBuffer(e).Length);
}
}
}