using PkmnLib.Static;

namespace PkmnLib.Tests.Static;

public class GrowthRateTests
{
    [Test]
    public async Task EmptyLookupGrowthRateTestShouldThrowArgumentException()
    {
        await Assert.That(() => { _ = new LookupGrowthRate("Test", []); }).Throws<ArgumentException>()
            .WithMessage("Experience table must have at least one entry.");
    }

    [Test]
    public async Task NonZeroLookupGrowthRateTestShouldThrowArgumentException()
    {
        await Assert.That(() => { _ = new LookupGrowthRate("Test", [1]); }).Throws<ArgumentException>()
            .WithMessage("Experience table must start at 0.");
    }

    [Test]
    public async Task TooLargeLookupGrowthRateTestShouldThrowArgumentException()
    {
        await Assert.That(() =>
            {
                _ = new LookupGrowthRate("Test", Enumerable.Range(0, LevelInt.MaxValue + 1).Select(i => (uint)i));
            }).Throws<ArgumentException>()
            .WithMessage($"Experience table may have at most {LevelInt.MaxValue} entries.");
    }

    [Test]
    public async Task LookupGrowthRateTest()
    {
        var growthRate = new LookupGrowthRate("Test", [0, 1, 2, 3, 4, 5]);
        await Assert.That(growthRate.CalculateLevel(0)).IsEqualTo((LevelInt)1);
        await Assert.That(growthRate.CalculateLevel(1)).IsEqualTo((LevelInt)2);
        await Assert.That(growthRate.CalculateLevel(2)).IsEqualTo((LevelInt)3);
        await Assert.That(growthRate.CalculateLevel(3)).IsEqualTo((LevelInt)4);
        await Assert.That(growthRate.CalculateLevel(4)).IsEqualTo((LevelInt)5);
        await Assert.That(growthRate.CalculateLevel(5)).IsEqualTo((LevelInt)6);

        await Assert.That(growthRate.CalculateExperience(1)).IsEqualTo((uint)0);
        await Assert.That(growthRate.CalculateExperience(2)).IsEqualTo((uint)1);
        await Assert.That(growthRate.CalculateExperience(3)).IsEqualTo((uint)2);
        await Assert.That(growthRate.CalculateExperience(4)).IsEqualTo((uint)3);
        await Assert.That(growthRate.CalculateExperience(5)).IsEqualTo((uint)4);
        await Assert.That(growthRate.CalculateExperience(6)).IsEqualTo((uint)5);
    }
}