using RioJoy.Core.Protocol;
using Xunit;

namespace RioJoy.Core.Tests.Protocol;

public class AnalogReportTests
{
    [Theory]
    [InlineData(0x00, 0x00, 0)]
    [InlineData(0x7F, 0x00, 127)]
    [InlineData(0x7F, 0x3F, 8191)]   // max positive 13-bit value
    [InlineData(0x00, 0x40, -8192)]  // bit 13 set → most negative
    [InlineData(0x7F, 0x7F, -1)]     // all 14 bits set → -1
    public void CombinePair_SignExtends14Bit(byte low, byte high, int expected)
    {
        Assert.Equal((short)expected, AnalogReport.CombinePair(low, high));
    }

    [Fact]
    public void TryParse_DecodesAxesInOrder()
    {
        // throttle=1, left=2, right=3, Y=4, X=5 (each from a low byte, high=0)
        var payload = new byte[] { 1, 0, 2, 0, 3, 0, 4, 0, 5, 0 };

        Assert.True(AnalogReport.TryParse(payload, out AnalogReport r));
        Assert.Equal(1, r.Throttle);
        Assert.Equal(2, r.LeftPedal);
        Assert.Equal(3, r.RightPedal);
        Assert.Equal(4, r.JoystickY);
        Assert.Equal(5, r.JoystickX);
    }

    [Fact]
    public void TryParse_RejectsRestartSentinel()
    {
        // A 0xFE anywhere in the payload marks the sample invalid.
        var payload = new byte[] { 1, 0, 2, 0, 0xFE, 0, 4, 0, 5, 0 };
        Assert.False(AnalogReport.TryParse(payload, out _));
    }

    [Fact]
    public void TryParse_RejectsWrongLength()
    {
        Assert.Throws<ArgumentException>(() => AnalogReport.TryParse(new byte[9], out _));
    }
}
