namespace ZB.MOM.WW.ScadaBridge.Commons.Messages.Management;

/// <summary>
/// Command (Central UI → site DCL manager) to verify a data-connection endpoint
/// configuration without persisting it: connect, capture the server certificate if it
/// is untrusted, then disconnect. The probe is read-only and never trusts the server
/// certificate — an untrusted certificate is captured and the connect is rejected
/// (cert trust is a separate, later action). Only OPC UA is supported today; other
/// protocols return a <see cref="VerifyEndpointResult"/> with
/// <see cref="VerifyFailureKind.ServerError"/>.
/// </summary>
/// <param name="ConnectionName">Name of the data connection being verified (for logging/correlation).</param>
/// <param name="Protocol">Protocol type string (e.g. "OpcUa"); matched case-insensitively.</param>
/// <param name="ConfigJson">Serialized endpoint configuration JSON (the typed OPC UA endpoint shape).</param>
/// <param name="SiteIdentifier">
/// Target site identifier — REQUIRED when the command is invoked via the management
/// HTTP API/CLI (the actor must route it to a site); ignored on the site side, where
/// routing already happened. Additive per the message-contract evolution rules.
/// </param>
public record VerifyEndpointCommand(string ConnectionName, string Protocol, string ConfigJson, string? SiteIdentifier = null);

/// <summary>
/// Classification of why an endpoint verification failed. Distinguishes the cases the
/// Central UI must present differently — most importantly
/// <see cref="UntrustedCertificate"/>, which carries a capturable server certificate the
/// operator can choose to trust in a later step.
/// </summary>
public enum VerifyFailureKind
{
    /// <summary>The endpoint host could not be reached (DNS failure, connection refused, socket error).</summary>
    Unreachable,

    /// <summary>The server rejected the supplied user identity (anonymous/username/certificate).</summary>
    AuthFailed,

    /// <summary>
    /// The server presented a certificate that is not trusted by this site. The
    /// certificate is captured in <see cref="VerifyEndpointResult.Cert"/> so it can be
    /// reviewed and trusted in a later step; the probe itself rejected it.
    /// </summary>
    UntrustedCertificate,

    /// <summary>The verification did not complete within the allotted time budget.</summary>
    Timeout,

    /// <summary>Any other server-side or unexpected failure (including unsupported protocol).</summary>
    ServerError
}

/// <summary>
/// Details of a server certificate captured during a verification probe. Carries the
/// fields the Central UI needs to display the certificate for an operator trust decision,
/// plus the raw DER (base64) so the certificate can be persisted to the trusted store
/// verbatim in a later step.
/// </summary>
/// <param name="Thumbprint">The certificate SHA-1 thumbprint (hex).</param>
/// <param name="Subject">The certificate subject distinguished name.</param>
/// <param name="Issuer">The certificate issuer distinguished name.</param>
/// <param name="NotBeforeUtc">The not-before validity bound (UTC).</param>
/// <param name="NotAfterUtc">The not-after validity bound (UTC).</param>
/// <param name="DerBase64">The raw DER-encoded certificate, base64-encoded.</param>
public record ServerCertInfo(
    string Thumbprint,
    string Subject,
    string Issuer,
    DateTime NotBeforeUtc,
    DateTime NotAfterUtc,
    string DerBase64);

/// <summary>
/// Result of a <see cref="VerifyEndpointCommand"/>. On success <see cref="FailureKind"/>,
/// <see cref="Error"/>, and <see cref="Cert"/> are all null. On failure
/// <see cref="FailureKind"/> classifies the failure and <see cref="Error"/> carries a
/// human-readable message; <see cref="Cert"/> is populated only when
/// <see cref="FailureKind"/> is <see cref="VerifyFailureKind.UntrustedCertificate"/>.
/// </summary>
/// <param name="Success">True if a session was established (the endpoint config is valid and reachable).</param>
/// <param name="FailureKind">The failure classification, or null on success.</param>
/// <param name="Error">A human-readable error message, or null on success.</param>
/// <param name="Cert">The captured untrusted server certificate, or null.</param>
public record VerifyEndpointResult(
    bool Success,
    VerifyFailureKind? FailureKind,
    string? Error,
    ServerCertInfo? Cert);
