using ZB.MOM.WW.Auth.Abstractions.Ldap;

namespace ZB.MOM.WW.MxGateway.Server.Configuration;

/// <summary>
/// Gateway-side view of the <c>MxGateway:Ldap</c> section. This is a SHADOW of the
/// shared <see cref="ZB.MOM.WW.Auth.Abstractions.Ldap.LdapOptions"/> type and is NOT
/// used to perform LDAP authentication at runtime — runtime bind/search is done by the
/// shared <c>ZB.MOM.WW.Auth.Ldap</c> provider, whose options are bound directly from the
/// same <c>MxGateway:Ldap</c> section by <c>AddZbLdapAuth</c> (see
/// <see cref="ZB.MOM.WW.MxGateway.Server.Dashboard.DashboardServiceCollectionExtensions"/>).
/// <para>
/// This shadow exists for three things only: (1) startup validation via
/// <see cref="GatewayOptionsValidator"/>; (2) the redacted effective-config display
/// (<see cref="EffectiveLdapConfiguration"/> / <see cref="GatewayConfigurationProvider"/>);
/// and (3) it is the single home of the gateway's dev/default LDAP values, which the
/// integration live-test helper copies onto the shared options.
/// </para>
/// <para>
/// Review C2 — DRIFT WARNING: this class MUST stay field-compatible with the shared
/// <see cref="ZB.MOM.WW.Auth.Abstractions.Ldap.LdapOptions"/> so the one config section
/// binds cleanly onto both. The two are intentionally NOT merged because their defaults
/// differ on purpose: this shadow ships dev-friendly defaults (plaintext localhost,
/// <c>AllowInsecure=true</c>, populated <c>SearchBase</c>/<c>ServiceAccount*</c>), whereas
/// the shared type is secure-by-default (<c>Transport=Ldaps</c>, <c>AllowInsecure=false</c>,
/// empty DN fields). If you add/rename/remove a field on the shared type, mirror it here
/// (and in the validator + effective-config) so the section keeps binding to both.
/// </para>
/// </summary>
public sealed class LdapOptions
{
    /// <summary>Gets a value indicating whether LDAP authentication is enabled.</summary>
    public bool Enabled { get; init; } = true;

    /// <summary>Gets the LDAP server address.</summary>
    public string Server { get; init; } = "localhost";

    /// <summary>Gets the LDAP server port.</summary>
    public int Port { get; init; } = 3893;

    /// <summary>
    /// Gets the transport/TLS mode for the LDAP connection. Replaces the former
    /// boolean <c>UseTls</c> (true ≈ <see cref="LdapTransport.Ldaps"/>, false =
    /// <see cref="LdapTransport.None"/>). <see cref="LdapTransport.StartTls"/> upgrades
    /// a plaintext connection to TLS. Matches the shared
    /// <see cref="ZB.MOM.WW.Auth.Abstractions.Ldap.LdapOptions.Transport"/> field so the
    /// <c>MxGateway:Ldap</c> section binds straight onto the shared options.
    /// </summary>
    public LdapTransport Transport { get; init; } = LdapTransport.None;

    /// <summary>Gets a value indicating whether insecure (plaintext) LDAP connections are allowed.</summary>
    public bool AllowInsecure { get; init; } = true;

    /// <summary>Gets the LDAP search base distinguished name.</summary>
    public string SearchBase { get; init; } = "dc=zb,dc=local";

    /// <summary>Gets the service account distinguished name.</summary>
    public string ServiceAccountDn { get; init; } = "cn=serviceaccount,dc=zb,dc=local";

    /// <summary>Gets the service account password.</summary>
    public string ServiceAccountPassword { get; init; } = string.Empty;

    /// <summary>Gets the LDAP attribute name for user names.</summary>
    public string UserNameAttribute { get; init; } = "cn";

    /// <summary>Gets the LDAP attribute name for display names.</summary>
    public string DisplayNameAttribute { get; init; } = "cn";

    /// <summary>Gets the LDAP attribute name for group membership.</summary>
    public string GroupAttribute { get; init; } = "memberOf";

    /// <summary>
    /// Gets the ordered fallback LDAP endpoints (<c>"host"</c> or <c>"host:port"</c>) the shared
    /// provider walks when the primary fails with a system-side error. Empty (the default) leaves
    /// single-endpoint behaviour unchanged. Mirrors
    /// <see cref="ZB.MOM.WW.Auth.Abstractions.Ldap.LdapOptions.FallbackServers"/>, added in
    /// ZB.MOM.WW.Auth 0.2.0.
    /// <para>
    /// Carried here only so the effective-config display does not hide a configured backup DC —
    /// nothing on the gateway side reads it. Entry syntax is validated at boot by the shared
    /// <c>LdapOptionsValidator</c>, which owns the (internal) parser; re-validating here would
    /// mean a second, drifting copy of that grammar.
    /// </para>
    /// </summary>
    public IReadOnlyList<string> FallbackServers { get; init; } = [];
}
