using Shouldly;
using Xunit;
using ZB.MOM.WW.OtOpcUa.Core.Abstractions;
using ZB.MOM.WW.OtOpcUa.Driver.AbLegacy;

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

/// <summary>
///     CONV-4 — <see cref="AbLegacyDriver.ResolveHost"/> must resolve a RawPath reference to its OWN
///     device host so per-host breaker keys are correct for multi-device tags, not the first-device
///     fallback. v3: the tag's device travels on the <see cref="RawTagEntry.DeviceName"/> the deploy
///     artifact delivers; the driver resolves it to that device's host at table-build time.
/// </summary>
[Trait("Category", "Unit")]
public sealed class AbLegacyResolveHostTests
{
    private const string DeviceA = "ab://10.0.0.5/1,0";
    private const string DeviceB = "ab://10.0.0.6/1,0";

    private static AbLegacyDriver NewDriver(params RawTagEntry[] rawTags) => new(
        new AbLegacyDriverOptions
        {
            Devices = [new AbLegacyDeviceOptions(DeviceA), new AbLegacyDeviceOptions(DeviceB)],
            RawTags = rawTags,
            Probe = new AbLegacyProbeOptions { Enabled = false },
        },
        "ablegacy-1", new FakeAbLegacyTagFactory());

    /// <summary>A raw tag owned by device B resolves to device B's host, not the first device.</summary>
    [Fact]
    public async Task ResolveHost_RawTagRef_ReturnsItsOwnDeviceHost()
    {
        const string rawPath = "cell/ablegacy/devB/T1";
        var drv = NewDriver(new RawTagEntry(
            rawPath, """{"address":"N7:0","dataType":"Int"}""", WriteIdempotent: false, DeviceName: DeviceB));
        await drv.InitializeAsync("{}", CancellationToken.None);

        drv.ResolveHost(rawPath).ShouldBe(DeviceB);
    }

    /// <summary>An unresolvable ref keeps the current first-device fallback.</summary>
    [Fact]
    public void ResolveHost_UnknownRef_KeepsCurrentFallback()
    {
        var drv = NewDriver();
        drv.ResolveHost("totally-unknown").ShouldBe(DeviceA);
    }
}
