using RioJoy.Core.Protocol;
using Xunit;

namespace RioJoy.Core.Tests.Protocol;

public class PacketBuilderTests
{
    [Fact]
    public void AnalogRequest_HasCommandAndChecksumOnly()
    {
        // 0x82, checksum = 0x82 & 0x7F = 0x02
        Assert.Equal(new byte[] { 0x82, 0x02 }, PacketBuilder.AnalogRequest());
    }

    [Fact]
    public void ResetRequest_EncodesTarget()
    {
        // 0x83, payload [0x00], checksum = 0x03
        Assert.Equal(new byte[] { 0x83, 0x00, 0x03 }, PacketBuilder.ResetRequest(RioResetTarget.All));
        // 0x83, payload [0x01], checksum = 0x04
        Assert.Equal(new byte[] { 0x83, 0x01, 0x04 }, PacketBuilder.ResetRequest(RioResetTarget.Throttle));
    }

    [Fact]
    public void LampRequest_EncodesLampAndState()
    {
        // 0x84, payload [0x05, 0x3C], checksum = (0x04 + 0x05 + 0x3C) & 0x7F = 0x45
        Assert.Equal(new byte[] { 0x84, 0x05, 0x3C, 0x45 }, PacketBuilder.LampRequest(5, 0x3C));
    }

    [Fact]
    public void Build_ValidatesPayloadLength()
    {
        Assert.Throws<ArgumentException>(() => PacketBuilder.Build(RioCommand.LampRequest, new byte[] { 0x01 }));
    }

    [Fact]
    public void Build_AppendsCorrectChecksum_ForFullPayload()
    {
        var payload = new byte[] { 1, 0, 2, 0, 3, 0, 4, 0, 5, 0 };
        byte[] packet = PacketBuilder.Build(RioCommand.AnalogReply, payload);

        Assert.Equal((byte)RioCommand.AnalogReply, packet[0]);
        Assert.Equal(payload, packet.Skip(1).Take(packet.Length - 2).ToArray());
        Assert.Equal(RioChecksum.Compute(packet, 0, packet.Length - 1), packet[packet.Length - 1]);
    }
}
