namespace ZB.MOM.WW.OtOpcUa.Cluster;

/// <summary>
///     Node-side selection of where a driver reads its deployed configuration (per-cluster mesh
///     Phase 3). The dark switch that lets a driver node stop reading <c>Deployment.ArtifactBlob</c>
///     from central SQL and instead fetch the artifact from central over gRPC and read it from the
///     pair-local LocalDb cache.
/// </summary>
public sealed class ConfigSourceOptions
{
    /// <summary>Configuration section name.</summary>
    public const string SectionName = "ConfigSource";

    /// <summary>Read config directly from central SQL — today's behaviour, and the default.</summary>
    public const string ModeDirect = "Direct";

    /// <summary>Fetch the artifact from central over gRPC, cache it in LocalDb, and read from there.</summary>
    public const string ModeFetchAndCache = "FetchAndCache";

    /// <summary>
    ///     <see cref="ModeDirect"/> (default) or <see cref="ModeFetchAndCache"/>. Any other value
    ///     fails host start.
    /// </summary>
    public string Mode { get; set; } = ModeDirect;

    /// <summary>
    ///     Central artifact-gRPC base addresses, e.g. <c>http://central-1:4055</c> (h2c ⇒ the
    ///     <c>http</c> scheme). Tried in order for failover. Required under
    ///     <see cref="ModeFetchAndCache"/>; ignored under <see cref="ModeDirect"/>.
    /// </summary>
    public string[] CentralFetchEndpoints { get; set; } = [];

    /// <summary>
    ///     Shared bearer key; must equal central's <see cref="ConfigServeOptions.ApiKey"/>. Supply via
    ///     the environment (<c>ConfigSource__ApiKey</c>) — never commit it. Required under
    ///     <see cref="ModeFetchAndCache"/>.
    /// </summary>
    public string ApiKey { get; set; } = string.Empty;

    /// <summary>Per-fetch deadline in seconds. Must be positive under <see cref="ModeFetchAndCache"/>.</summary>
    public int FetchTimeoutSeconds { get; set; } = 30;
}

/// <summary>
///     Central-side artifact-serve surface (per-cluster mesh Phase 3). Configures the dedicated h2c
///     listener + shared bearer key the <c>DeploymentArtifactService</c> is exposed behind. Only
///     admin-role nodes (which hold the central SQL connection) serve.
/// </summary>
public sealed class ConfigServeOptions
{
    /// <summary>Configuration section name.</summary>
    public const string SectionName = "ConfigServe";

    /// <summary>
    ///     Dedicated HTTP/2-only (h2c) listener port for the artifact gRPC service. <c>0</c> (the
    ///     default) disables it — nothing is bound. Must differ from the main HTTP port and from
    ///     <c>LocalDb:SyncListenPort</c> (h2c cannot share a cleartext HTTP/1 port).
    /// </summary>
    public int GrpcListenPort { get; set; }

    /// <summary>
    ///     Shared bearer key the serve-side interceptor checks (constant-time, fail-closed: an unset
    ///     key rejects every call). Supply via the environment (<c>ConfigServe__ApiKey</c>) — never
    ///     commit it.
    /// </summary>
    public string ApiKey { get; set; } = string.Empty;
}
