using Shouldly;
using Xunit;
using ZB.MOM.WW.OtOpcUa.AdminUI.Components.Shared.Drivers.DeviceForms;

namespace ZB.MOM.WW.OtOpcUa.AdminUI.Tests.Uns;

/// <summary>
///     Round-trip guard for the Modbus <b>device</b> endpoint model — the gate-critical DeviceConfig
///     surface. Endpoint keys MUST be PascalCase (Host/Port/UnitId) so the merged probe config binds via
///     the runtime's case-insensitive deserializer, matching the seed and Wave-B service tests.
/// </summary>
public sealed class ModbusDeviceModelTests
{
    [Theory]
    [InlineData(null)]
    [InlineData("")]
    [InlineData("   ")]
    [InlineData("{}")]
    public void FromJson_returns_defaults_for_empty_input(string? json)
    {
        var m = ModbusDeviceModel.FromJson(json);

        m.Host.ShouldBe("127.0.0.1");
        m.Port.ShouldBe(502);
        m.UnitId.ShouldBe(1);
    }

    [Fact]
    public void Round_trip_preserves_endpoint_fields()
    {
        var m = new ModbusDeviceModel { Host = "10.100.0.35", Port = 5020, UnitId = 7 };

        var json = m.ToJson();
        var m2 = ModbusDeviceModel.FromJson(json);

        m2.Host.ShouldBe("10.100.0.35");
        m2.Port.ShouldBe(5020);
        m2.UnitId.ShouldBe(7);
    }

    [Fact]
    public void ToJson_emits_PascalCase_endpoint_keys()
    {
        var json = new ModbusDeviceModel { Host = "10.1.2.3", Port = 5020, UnitId = 1 }.ToJson();

        // Runtime binds ModbusDriverOptions.Host/Port/UnitId from these exact PascalCase keys.
        json.ShouldContain("\"Host\":\"10.1.2.3\"");
        json.ShouldContain("\"Port\":5020");
        json.ShouldContain("\"UnitId\":1");
    }

    [Fact]
    public void FromJson_then_ToJson_preserves_unknown_keys()
    {
        var json = ModbusDeviceModel
            .FromJson("""{"Host":"10.1.2.3","Port":5020,"UnitId":1,"customKey":"keepme"}""")
            .ToJson();

        json.ShouldContain("customKey");
        json.ShouldContain("keepme");
        json.ShouldContain("\"Host\":\"10.1.2.3\"");
    }

    [Fact]
    public void Validate_flags_blank_host()
    {
        new ModbusDeviceModel { Host = "" }.Validate().ShouldNotBeNull();
        new ModbusDeviceModel { Host = "127.0.0.1" }.Validate().ShouldBeNull();
    }
}
