using Shouldly;
using Xunit;

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

/// <summary>
///     Gitea #516 — <c>AbLegacyDriver.InitializeAsync</c> used to serve the options its CONSTRUCTOR
///     captured and never look at the <c>driverConfigJson</c> it was handed, so an operator's config edit
///     was silently discarded while the deployment still sealed green.
///     <para>Every pre-existing reinit test in this suite passes <c>"{}"</c> — the exact input the guarded
///     re-parser treats as "keep the constructor options" — so they were blind to the defect.</para>
/// </summary>
[Trait("Category", "Unit")]
public sealed class AbLegacyReinitConfigAdoptionTests
{
    /// <summary>
    ///     The driver validates every device's <c>HostAddress</c> during init. Reinitializing with a config
    ///     whose device address is structurally invalid must therefore THROW — a driver still serving the
    ///     constructor's valid device list would validate that instead and succeed, which is precisely how
    ///     the discarded edit stayed invisible.
    /// </summary>
    [Fact]
    public async Task Reinitialize_adopts_a_changed_device_list()
    {
        var driver = AbLegacyDriverFactoryExtensions.CreateInstance(
            "ab1",
            """{"devices":[{"hostAddress":"ab://10.0.0.1:44818/1,0","plcFamily":"Slc500"}]}""",
            loggerFactory: null);

        await Should.ThrowAsync<InvalidOperationException>(
            () => driver.ReinitializeAsync(
                """{"devices":[{"hostAddress":"not-a-valid-ab-address","plcFamily":"Slc500"}]}""",
                CancellationToken.None),
            "AbLegacyDriver kept its constructor-supplied device list after a reinitialize with a changed config (#516)");
    }

    /// <summary>An empty/placeholder document must still keep the constructor options, so the many
    /// lifecycle tests that pass <c>"{}"</c> keep meaning what they meant.</summary>
    [Fact]
    public async Task Reinitialize_with_an_empty_document_keeps_the_constructor_options()
    {
        var driver = AbLegacyDriverFactoryExtensions.CreateInstance(
            "ab1",
            """{"devices":[{"hostAddress":"ab://10.0.0.1:44818/1,0","plcFamily":"Slc500"}]}""",
            loggerFactory: null);

        await Should.NotThrowAsync(() => driver.ReinitializeAsync("{}", CancellationToken.None));
    }
}
