using ZB.MOM.WW.Configuration;
namespace ZB.MOM.WW.ScadaBridge.Host;
///
/// Validates at host startup (arch-review 08 round 2
/// NF4). The headline invariant: must be
/// non-empty — an empty value normalises to a NULL SourceNode audit
/// column, silently degrading the audit trail (the wonder-app-vd03 failure
/// mode), so the host must fail fast at boot instead. Ports are bounded to the
/// TCP range; 0 stays valid because it requests a dynamically-assigned
/// port (CompositionRootTests rely on this).
///
public sealed class NodeOptionsValidator : OptionsValidatorBase
{
///
protected override void Validate(ValidationBuilder builder, NodeOptions options)
{
builder.RequireThat(!string.IsNullOrWhiteSpace(options.NodeName),
$"ScadaBridge:Node:{nameof(NodeOptions.NodeName)} must be a non-empty label " +
"— an empty node name stamps the SourceNode audit column NULL.");
RequirePort(builder, options.RemotingPort, nameof(NodeOptions.RemotingPort));
RequirePort(builder, options.GrpcPort, nameof(NodeOptions.GrpcPort));
RequirePort(builder, options.MetricsPort, nameof(NodeOptions.MetricsPort));
RequirePort(builder, options.CentralGrpcPort, nameof(NodeOptions.CentralGrpcPort));
}
// 0 stays valid (dynamic-port request); reject only out-of-TCP-range values.
private static void RequirePort(ValidationBuilder builder, int port, string field)
{
builder.RequireThat(port is >= 0 and <= 65_535,
$"ScadaBridge:Node:{field} ({port}) must be in [0, 65535].");
}
}