namespace ZB.MOM.WW.OtOpcUa.Driver.AbCip;
///
/// The ONE place an AbCip driver's effective transport is decided from its configured
/// . The driver constructor, the Test Connect probe and the
/// CLI (through the driver) all resolve through here, so they cannot disagree about what an absent
/// transport key means.
/// Precedence (final review I1): an explicit per-driver transport key wins; otherwise the
/// node-level default (Drivers:AbCip:DefaultTransport, read in the Host composition root and passed
/// in as nodeDefault); otherwise the compiled .
///
public static class AbCipTransportResolver
{
/// The compiled default: the transport an absent key selects when no node default is configured.
public const AbCipTransport Default = AbCipTransport.Native;
/// Returns the effective transport: an explicit value always wins; null means .
/// The configured transport, or null for "use the default".
/// The node-level default for drivers with no key (the compiled unless pinned).
/// The transport the driver runs on.
public static AbCipTransport Resolve(AbCipTransport? configured, AbCipTransport nodeDefault = Default) =>
configured ?? nodeDefault;
/// Returns the effective transport for .
/// The driver options.
/// The node-level default for drivers with no key.
/// The transport the driver runs on.
public static AbCipTransport Resolve(AbCipDriverOptions options, AbCipTransport nodeDefault = Default)
{
ArgumentNullException.ThrowIfNull(options);
return Resolve(options.Transport, nodeDefault);
}
///
/// Parses a transport name the way the driver-config transport key and the node-level default
/// are parsed: a defined enum NAME, case-insensitive. Numeric strings ("0", "7") and the flags form
/// ("Native,Libplctag") are rejected — Enum.TryParse alone accepts both.
///
/// The raw value.
/// The parsed transport.
/// True when names a transport.
public static bool TryParse(string? raw, out AbCipTransport transport)
{
transport = Default;
if (string.IsNullOrWhiteSpace(raw)) return false;
// Exact name match only: Enum.TryParse would also accept "1" and the flags form "Native,Libplctag".
var name = Enum.GetNames()
.FirstOrDefault(n => string.Equals(n, raw.Trim(), StringComparison.OrdinalIgnoreCase));
return name is not null && Enum.TryParse(name, out transport);
}
///
/// Operator-facing description of the configured-vs-effective transport for the init log line:
/// Native (default) when the key was absent and the compiled default applies,
/// Libplctag (node default) when the key was absent and the node pinned a different default,
/// Native (configured) when the key was explicit.
///
/// The configured transport, or null.
/// The node-level default.
/// A short description.
public static string Describe(AbCipTransport? configured, AbCipTransport nodeDefault = Default) =>
configured is not null ? $"{configured} (configured)"
: nodeDefault == Default ? $"{nodeDefault} (default)"
: $"{nodeDefault} (node default)";
}