namespace ScadaLink.Security;

public class SecurityOptions
{
    public string LdapServer { get; set; } = string.Empty;
    public int LdapPort { get; set; } = 389;

    /// <summary>
    /// Transport security mode for the LDAP connection. Defaults to LDAPS.
    /// Use <see cref="LdapTransport.StartTls"/> to connect on the plaintext port
    /// and upgrade the session before binding.
    /// </summary>
    public LdapTransport LdapTransport { get; set; } = LdapTransport.Ldaps;

    /// <summary>
    /// True when the configured transport provides encryption (LDAPS or StartTLS).
    /// Retained for backward compatibility: assigning a value maps onto
    /// <see cref="LdapTransport"/> (true =&gt; LDAPS, false =&gt; None).
    /// </summary>
    public bool LdapUseTls
    {
        get => LdapTransport != LdapTransport.None;
        set => LdapTransport = value ? LdapTransport.Ldaps : LdapTransport.None;
    }

    /// <summary>
    /// Allow insecure (non-TLS) LDAP connections. ONLY for dev/test with GLAuth.
    /// Must be false in production.
    /// </summary>
    public bool AllowInsecureLdap { get; set; } = false;

    /// <summary>
    /// Base DN for LDAP searches (e.g., "dc=example,dc=com").
    /// </summary>
    public string LdapSearchBase { get; set; } = string.Empty;

    /// <summary>
    /// Service account DN for LDAP user searches (e.g., "cn=admin,dc=example,dc=com").
    /// Required for search-then-bind authentication. If empty, direct bind with
    /// {LdapUserIdAttribute}={username},{LdapSearchBase} is attempted instead.
    /// </summary>
    public string LdapServiceAccountDn { get; set; } = string.Empty;

    /// <summary>
    /// LDAP attribute that identifies a user. Used both for the search-then-bind
    /// filter (<c>({LdapUserIdAttribute}={username})</c>) and for constructing the
    /// fallback bind DN when no service account is configured, so the two
    /// authentication modes are interchangeable. Common values: <c>uid</c> (OpenLDAP),
    /// <c>sAMAccountName</c> (Active Directory).
    /// </summary>
    public string LdapUserIdAttribute { get; set; } = "uid";

    /// <summary>
    /// Service account password for LDAP user searches.
    /// </summary>
    public string LdapServiceAccountPassword { get; set; } = string.Empty;

    /// <summary>
    /// LDAP attribute that contains the user's display name.
    /// </summary>
    public string LdapDisplayNameAttribute { get; set; } = "cn";

    /// <summary>
    /// LDAP attribute that contains group membership.
    /// </summary>
    public string LdapGroupAttribute { get; set; } = "memberOf";

    /// <summary>
    /// Symmetric HMAC-SHA256 signing key for cookie-embedded JWTs. Must be at least
    /// 32 bytes (256 bits) — validated at <see cref="JwtTokenService"/> construction.
    /// </summary>
    public string JwtSigningKey { get; set; } = string.Empty;

    /// <summary>
    /// Minimum signing-key length in bytes required for HMAC-SHA256 (256 bits).
    /// </summary>
    public const int MinJwtSigningKeyBytes = 32;
    public int JwtExpiryMinutes { get; set; } = 15;
    public int IdleTimeoutMinutes { get; set; } = 30;

    /// <summary>
    /// Minutes before token expiry to trigger refresh.
    /// </summary>
    public int JwtRefreshThresholdMinutes { get; set; } = 5;
}
