using Shouldly;
using Xunit;
using ZB.MOM.WW.OtOpcUa.AdminUI.Uns.TagEditors;

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

/// <summary>
///     R2-11 (05/UNDER-6): the new optional <c>writable</c> key round-trips through the driver-typed tag
///     config models — a value the editors' new checkbox authors. Absent stays absent (so existing configs
///     are untouched); an explicit <c>false</c> round-trips; unknown keys are preserved.
/// </summary>
public sealed class TagConfigModelWritableTests
{
    [Fact]
    public void Modbus_absent_writable_stays_omitted()
    {
        var m = ModbusTagConfigModel.FromJson("{\"region\":\"HoldingRegisters\",\"address\":1,\"dataType\":\"Int16\"}");
        m.Writable.ShouldBeNull();
        m.ToJson().ShouldNotContain("writable");
    }

    [Fact]
    public void Modbus_explicit_false_round_trips()
    {
        var m = ModbusTagConfigModel.FromJson("{\"address\":1,\"writable\":false}");
        m.Writable.ShouldBe(false);
        var json = ModbusTagConfigModel.FromJson(m.ToJson());
        json.Writable.ShouldBe(false);
    }

    [Fact]
    public void Modbus_setting_writable_true_writes_the_key()
    {
        var m = ModbusTagConfigModel.FromJson("{\"address\":1}");
        m.Writable = true;
        ModbusTagConfigModel.FromJson(m.ToJson()).Writable.ShouldBe(true);
    }

    [Fact]
    public void Writable_preserves_unknown_keys()
    {
        var m = ModbusTagConfigModel.FromJson("{\"address\":1,\"writable\":false,\"foo\":\"bar\"}");
        m.ToJson().ShouldContain("foo");
        m.ToJson().ShouldContain("bar");
    }

    [Fact]
    public void S7_writable_round_trips()
    {
        var m = S7TagConfigModel.FromJson("{\"address\":\"DB1.DBW0\",\"writable\":false}");
        m.Writable.ShouldBe(false);
        S7TagConfigModel.FromJson(m.ToJson()).Writable.ShouldBe(false);
    }

    [Fact]
    public void AbCip_writable_round_trips()
    {
        var m = AbCipTagConfigModel.FromJson("{\"tagPath\":\"Motor.Speed\",\"writable\":false}");
        m.Writable.ShouldBe(false);
        AbCipTagConfigModel.FromJson(m.ToJson()).Writable.ShouldBe(false);
    }

    [Fact]
    public void AbLegacy_writable_round_trips()
    {
        var m = AbLegacyTagConfigModel.FromJson("{\"address\":\"N7:0\",\"writable\":false}");
        m.Writable.ShouldBe(false);
        AbLegacyTagConfigModel.FromJson(m.ToJson()).Writable.ShouldBe(false);
    }

    [Fact]
    public void TwinCAT_writable_round_trips()
    {
        var m = TwinCATTagConfigModel.FromJson("{\"symbolPath\":\"MAIN.x\",\"writable\":false}");
        m.Writable.ShouldBe(false);
        TwinCATTagConfigModel.FromJson(m.ToJson()).Writable.ShouldBe(false);
    }

    [Fact]
    public void Absent_writable_omitted_across_models()
    {
        ModbusTagConfigModel.FromJson("{\"address\":1}").ToJson().ShouldNotContain("writable");
        S7TagConfigModel.FromJson("{\"address\":\"DB1.DBW0\"}").ToJson().ShouldNotContain("writable");
        AbCipTagConfigModel.FromJson("{\"tagPath\":\"M.S\"}").ToJson().ShouldNotContain("writable");
        AbLegacyTagConfigModel.FromJson("{\"address\":\"N7:0\"}").ToJson().ShouldNotContain("writable");
        TwinCATTagConfigModel.FromJson("{\"symbolPath\":\"MAIN.x\"}").ToJson().ShouldNotContain("writable");
    }
}
