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

/// <summary>
///     Parsed <c>ab://gateway[:port]/cip-path</c> host-address string for AB Legacy devices.
///     Same format as AbCip — PCCC-over-EIP uses the same gateway + optional routing path as
///     the CIP family (a PLC-5 bridged through a ControlLogix chassis takes the full CIP path;
///     a direct-wired SLC 500 uses an empty path).
/// </summary>
/// <remarks>
///     Parser duplicated from AbCipHostAddress rather than shared because the two drivers ship
///     independently + a shared helper would force a reference between them. If a third AB
///     driver appears, extract into Core.Abstractions.
/// </remarks>
public sealed record AbLegacyHostAddress(string Gateway, int Port, string CipPath)
{
    public const int DefaultEipPort = 44818;

    /// <inheritdoc />
    public override string ToString() => Port == DefaultEipPort
        ? $"ab://{Gateway}/{CipPath}"
        : $"ab://{Gateway}:{Port}/{CipPath}";

    /// <summary>Attempts to parse an AB host address string in the format ab://gateway[:port]/cip-path.</summary>
    /// <param name="value">The host address string to parse.</param>
    /// <returns>The parsed host address, or null if the format is invalid.</returns>
    public static AbLegacyHostAddress? TryParse(string? value)
    {
        if (string.IsNullOrWhiteSpace(value)) return null;
        const string prefix = "ab://";
        if (!value.StartsWith(prefix, StringComparison.OrdinalIgnoreCase)) return null;

        var remainder = value[prefix.Length..];
        var slashIdx = remainder.IndexOf('/');
        if (slashIdx < 0) return null;

        var authority = remainder[..slashIdx];
        var cipPath = remainder[(slashIdx + 1)..];
        if (string.IsNullOrEmpty(authority)) return null;

        var port = DefaultEipPort;
        var colonIdx = authority.LastIndexOf(':');
        string gateway;
        if (colonIdx >= 0)
        {
            gateway = authority[..colonIdx];
            if (!int.TryParse(authority[(colonIdx + 1)..], out port) || port is <= 0 or > 65535)
                return null;
        }
        else
        {
            gateway = authority;
        }
        if (string.IsNullOrEmpty(gateway)) return null;

        return new AbLegacyHostAddress(gateway, port, cipPath);
    }
}
