using Xunit;

namespace ZB.MOM.WW.OtOpcUa.Driver.AbCip.IntegrationTests;

/// <summary>
///     Runtime gate that lets an integration-test class declare which target-server tier
///     it requires. Reads <c>AB_SERVER_PROFILE</c> from the environment; tests call
///     <see cref="SkipUnless"/> with the profile names they support + skip otherwise.
/// </summary>
/// <remarks>
///     <para>Two tiers today:</para>
///     <list type="bullet">
///       <item><c>abserver</c> (default) — the Dockerized libplctag <c>ab_server</c>
///         simulator. Covers atomic reads / writes / basic discovery across the four
///         families (ControlLogix / CompactLogix / Micro800 / GuardLogix).</item>
///       <item><c>emulate</c> — Rockwell Studio 5000 Logix Emulate on an operator's
///         Windows box, exposed via <c>AB_SERVER_ENDPOINT</c>. Adds real UDT / ALMD /
///         AOI / Program-scoped-tag coverage that ab_server can't emulate. Tier-gated
///         because Emulate is per-seat licensed + Windows-only + manually launched;
///         a stock `dotnet test` run against ab_server must skip Emulate-only classes
///         cleanly.</item>
///     </list>
///     <para>Tests assert their target tier at the top of each <c>[Fact]</c> /
///     <c>[Theory]</c> body, mirroring the <c>MODBUS_SIM_PROFILE</c> gate pattern in
///     <c>tests/.../Modbus.IntegrationTests/DL205/DL205StringQuirkTests.cs</c>.</para>
/// </remarks>
public static class AbServerProfileGate
{
    public const string Default = "abserver";
    public const string Emulate = "emulate";

    /// <summary>Active profile from <c>AB_SERVER_PROFILE</c>; defaults to <see cref="Default"/>.</summary>
    public static string CurrentProfile =>
        Environment.GetEnvironmentVariable("AB_SERVER_PROFILE") is { Length: > 0 } raw
            ? raw.Trim().ToLowerInvariant()
            : Default;

    /// <summary>
    ///     Skip the calling test via <c>Assert.Skip</c> when <see cref="CurrentProfile"/>
    ///     isn't in <paramref name="requiredProfiles"/>. Case-insensitive match.
    /// </summary>
    /// <param name="requiredProfiles">The list of profile names to check against the current profile.</param>
    public static void SkipUnless(params string[] requiredProfiles)
    {
        foreach (var p in requiredProfiles)
            if (string.Equals(p, CurrentProfile, StringComparison.OrdinalIgnoreCase))
                return;
        Assert.Skip(
            $"Test requires AB_SERVER_PROFILE in {{{string.Join(", ", requiredProfiles)}}}; " +
            $"current value is '{CurrentProfile}'. " +
            $"Set AB_SERVER_PROFILE=emulate + point AB_SERVER_ENDPOINT at a Logix Emulate instance to run the golden-box-tier tests.");
    }
}
