namespace splat;

using System.Threading.Tasks;
using Chickensoft.GoDotTest;
using Chickensoft.GodotTestDriver;
using Godot;
using Shouldly;

public class TrafficTest : TestClass
{
    private Fixture _fixture = default!;

    public TrafficTest(Node testScene) : base(testScene) { }

    [SetupAll]
    public async Task Setup()
    {
        _fixture = new Fixture(TestScene.GetTree());
    }

    [CleanupAll]
    public void Cleanup() => _fixture.Cleanup();

    [Test]
    public void RoadDataQualityFactorDropsWithWear()
    {
        var data = new RoadData { Wear = 0f, QualityAtFullWear = 0.3f };
        data.QualityFactor().ShouldBe(1f);

        data.Wear = 1f;
        data.QualityFactor().ShouldBe(0.3f);
    }

    [Test]
    public void RoadWearAccumulatesAndDegrades()
    {
        var data = new RoadData
        {
            Material = RoadMaterial.Tarmac,
            Wear = 0f,
            BaseWearRate = 0.1f
        };
        // RegisterTraffic only mutates Data; the node need not be in the tree.
        var road = new Road { Data = data };

        var degraded = false;
        road.Degraded += _ => degraded = true;

        // 12 passes at 0.1 rate / resistance 1 = 1.2 -> clamped to 1 (degraded).
        for (var i = 0; i < 12; i++)
            road.RegisterTraffic(passes: 1f);

        data.Wear.ShouldBe(1f);
        degraded.ShouldBeTrue();
        road.Free();
    }

    [Test]
    public void VehicleDataHasSensibleDefaults()
    {
        var data = new VehicleData { Type = VehicleData.Kind.Car, Mass = 1200f };
        data.Acceleration.ShouldBeGreaterThan(0f);
        data.MaxSpeed.ShouldBeGreaterThan(0f);
        data.Braking.ShouldBeGreaterThan(data.Acceleration);
    }
}
