using Shouldly;
using Xunit;

namespace ZB.MOM.WW.OtOpcUa.Driver.Modbus.Tests;

public sealed class ModbusCrcTests
{
    // Known CRC-16/MODBUS vectors (init 0xFFFF, poly 0xA001). CRC returned as ushort;
    // on the wire it is appended low-byte-first.
    [Theory]
    // FC03 read HR: unit 1, addr 0, qty 1  -> CRC 0x0A84  (bytes 84 0A on the wire)
    [InlineData(new byte[] { 0x01, 0x03, 0x00, 0x00, 0x00, 0x01 }, (ushort)0x0A84)]
    // "123456789" canonical check value for CRC-16/MODBUS = 0x4B37
    [InlineData(new byte[] { 0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39 }, (ushort)0x4B37)]
    public void Compute_matches_known_vectors(byte[] frame, ushort expected)
        => ModbusCrc.Compute(frame).ShouldBe(expected);

    [Fact]
    public void AppendLowByteFirst_writes_lo_then_hi()
    {
        var body = new byte[] { 0x01, 0x03, 0x00, 0x00, 0x00, 0x01 };
        var withCrc = ModbusCrc.Append(body);
        withCrc.Length.ShouldBe(body.Length + 2);
        withCrc[^2].ShouldBe((byte)0x84); // CRC low byte
        withCrc[^1].ShouldBe((byte)0x0A); // CRC high byte
    }
}
