using Shouldly;
using Xunit;
using ZB.MOM.WW.OtOpcUa.Driver.FOCAS.Wire;
namespace ZB.MOM.WW.OtOpcUa.Driver.FOCAS.Tests;
///
/// Axis-name (0x0089) / spindle-name (0x008A) record decode. Each record is 4 bytes; the name is
/// the ASCII up to the record's FIRST NUL. Ported from the sister ignitionoee FOCAS driver
/// (Focas.Wire-001 and Focas.Wire-022, v0.18.1).
///
///
/// Reading only 2 bytes collides real names. The live 31i-B capture
/// (ref-axisname-0x0089.bin) carries "AA6" and "AA7"; the old 2-byte read
/// turned both into "AA", which is exactly the "one observed Makino returns two axis
/// folders both called AA" that Gitea #548 then had to disambiguate as AA_1/AA_2.
/// Trailing-only trimming keeps buffer residue. A control writes only the bytes the
/// name needs; on Makino Z-34184 (2026-08-19) cnc_rdspdlname came back
/// 53 31 00 4e — "S1" then the 'N' of an earlier "CNC". The name
/// ends at the first NUL.
///
[Trait("Category", "Unit")]
public sealed class FocasNameRecordTests
{
[Fact]
public void The_live_axis_name_capture_keeps_three_character_names_distinct()
{
var payload = WireFixtures.Payload("ref-axisname-0x0089.bin", 0x0089);
var names = FocasWireClient.ReadNameRecords(payload, 32, (index, name) => (index, name));
names.Select(n => n.name).ShouldBe(["X", "Y", "Z", "B", "C", "AA6", "AA7"]);
names.Select(n => n.index).ShouldBe([(short)1, 2, 3, 4, 5, 6, 7]);
}
[Fact]
public void The_live_spindle_name_capture_decodes()
{
var payload = WireFixtures.Payload("ref-spdlname-0x008a.bin", 0x008a);
FocasWireClient.ReadNameRecords(payload, 8, (_, name) => name).ShouldBe(["S1"]);
}
[Fact]
public void A_name_ends_at_its_first_NUL_so_residue_after_it_is_discarded()
{
// The Z-34184 spindle-name record: "S1", NUL, then an 'N' left over from a previous "CNC".
FocasWireProtocol.ReadNameRecord([0x53, 0x31, 0x00, 0x4e]).ShouldBe("S1");
// A single-character name with residue in BOTH trailing bytes.
FocasWireProtocol.ReadNameRecord([0x58, 0x00, 0x43, 0x4e]).ShouldBe("X");
}
[Fact]
public void All_four_record_bytes_are_name_bytes()
{
FocasWireProtocol.ReadNameRecord("AA6\0"u8.ToArray()).ShouldBe("AA6");
FocasWireProtocol.ReadNameRecord("ABCD"u8.ToArray()).ShouldBe("ABCD");
FocasWireProtocol.ReadNameRecord("X \0\0"u8.ToArray()).ShouldBe("X");
}
[Fact]
public void A_record_that_starts_with_NUL_is_blank()
{
FocasWireProtocol.ReadNameRecord([0x00, 0x41, 0x41, 0x00]).ShouldBe(string.Empty);
}
[Fact]
public void Servo_meter_names_come_out_whole_too()
{
var blocks = WireFixtures.Blocks("svmeter-pair-0x0056-0x0089.bin");
var sv = blocks.First(b => b.Command == 0x0056).Payload;
var names = blocks.First(b => b.Command == 0x0089).Payload;
var meters = FocasWireClient.ParseServoMeters(sv, names, maxCount: 32);
meters.Take(7).Select(m => m.Name).ShouldBe(["X", "Y", "Z", "B", "C", "AA6", "AA7"]);
}
}