using NUnit.Framework;
using ProjectM.Server;
using ProjectM.Simulation;
using Unity.Core;
using Unity.Entities;
using Unity.Mathematics;
using Unity.Transforms;
namespace ProjectM.Tests
{
///
/// Regression test for the teardown region-filter. When the last player
/// leaves the expedition the field is cleared — but that teardown must destroy ONLY RegionTag{Expedition}
/// nodes, never the permanent RegionTag{Base} home-base mining field. Before the fix the unfiltered teardown
/// wiped every ResourceNode on the empty edge (a despawn storm beside base players that broke the core loop).
///
public class ExpeditionFieldTeardownTests
{
[Test]
public void Expedition_Empty_Edge_Destroys_Only_Expedition_Nodes_Base_Field_Survives()
{
var world = new World("ExpeditionTeardown");
using (world)
{
var group = world.GetOrCreateSystemManaged();
group.AddSystemToUpdateList(world.GetOrCreateSystem());
group.SortSystems();
world.SetTime(new TimeData(elapsedTime: 0f, deltaTime: 1f / 60f));
var em = world.EntityManager;
// Cycle director: was occupied last tick, nobody out there now => the occupied->empty edge fires.
var cycle = em.CreateEntity(typeof(CycleState), typeof(CycleRuntime));
em.SetComponentData(cycle, new CycleState { Phase = CyclePhase.Calm, CycleNumber = 1 });
em.SetComponentData(cycle, new CycleRuntime { PrevExpeditionOccupied = 1 });
// Spawner singleton (required); null prefab so the spawn branch is inert.
var spawnerE = em.CreateEntity(typeof(ResourceFieldSpawner));
em.SetComponentData(spawnerE, new ResourceFieldSpawner { Prefab = Entity.Null, Count = 5, Radius = 10f });
var baseNode = em.CreateEntity(typeof(LocalTransform), typeof(ResourceNode), typeof(RegionTag));
em.SetComponentData(baseNode, LocalTransform.FromPosition(new float3(20, 0, 0)));
em.SetComponentData(baseNode, new ResourceNode { ResourceId = ResourceId.Ore, Remaining = 30, HarvestPerHit = 5f });
em.SetComponentData(baseNode, new RegionTag { Region = RegionId.Base });
var expNode = em.CreateEntity(typeof(LocalTransform), typeof(ResourceNode), typeof(RegionTag));
em.SetComponentData(expNode, LocalTransform.FromPosition(new float3(1020, 0, 0)));
em.SetComponentData(expNode, new ResourceNode { ResourceId = ResourceId.Aether, Remaining = 30, HarvestPerHit = 5f });
em.SetComponentData(expNode, new RegionTag { Region = RegionId.Expedition });
group.Update();
Assert.IsTrue(em.Exists(baseNode), "The permanent base mining field survives the expedition teardown.");
Assert.IsFalse(em.Exists(expNode), "Only the expedition node is cleared when the last player leaves.");
}
}
}
}