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

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

public sealed class TagConfigValidatorTests
{
    [Fact]
    public void No_driver_type_is_valid()
        => TagConfigValidator.Validate(null, "{}").ShouldBeNull();

    [Fact]
    public void Unmapped_driver_has_no_typed_validator_so_is_valid()
        => TagConfigValidator.Validate("GalaxyMxGateway", "{}").ShouldBeNull();

    [Fact]
    public void Modbus_has_no_required_field_so_empty_config_is_valid()
        => TagConfigValidator.Validate("Modbus", "{}").ShouldBeNull();

    [Fact]
    public void Resolve_Modbus_dispatches_typed_editor()
        => TagConfigEditorMap.Resolve("Modbus")
            .ShouldBe(typeof(ZB.MOM.WW.OtOpcUa.AdminUI.Components.Shared.Uns.TagEditors.ModbusTagConfigEditor));

    // Drivers whose Validate() requires a field: blank config must return an error string.
    [Theory]
    [InlineData("S7")]
    [InlineData("AbCip")]
    [InlineData("AbLegacy")]
    [InlineData("TwinCat")]
    [InlineData("Focas")]
    [InlineData("OpcUaClient")]
    public void Required_field_blank_is_rejected(string driverType)
    {
        TagConfigValidator.Validate(driverType, "{}").ShouldNotBeNullOrEmpty();
        TagConfigValidator.Validate(driverType, null).ShouldNotBeNullOrEmpty();
    }

    // v3 Batch-1: the OpcUaClient editor's address key was renamed FullName → nodeId (camelCase).
    [Fact]
    public void OpcUaClient_with_node_id_is_valid()
        => TagConfigValidator.Validate("OpcUaClient", """{"nodeId":"ns=2;s=Line3.Temp"}""").ShouldBeNull();

    [Fact]
    public void S7_with_address_is_valid()
        => TagConfigValidator.Validate("S7", """{"address":"DB1.DBW0"}""").ShouldBeNull();

    [Fact]
    public void AbCip_with_tag_path_is_valid()
        => TagConfigValidator.Validate("AbCip", """{"tagPath":"Program:Main.Speed"}""").ShouldBeNull();

    [Fact]
    public void TwinCat_with_symbol_path_is_valid()
        => TagConfigValidator.Validate("TwinCat", """{"symbolPath":"MAIN.bStart"}""").ShouldBeNull();

    [Fact]
    public void Driver_type_lookup_is_case_insensitive()
        => TagConfigValidator.Validate("s7", "{}").ShouldNotBeNullOrEmpty();
}
