namespace ZB.MOM.WW.OtOpcUa.Client.Shared.Models;

/// <summary>
///     Settings for establishing an OPC UA client connection.
/// </summary>
public sealed class ConnectionSettings
{
    /// <summary>
    ///     The primary OPC UA endpoint URL.
    /// </summary>
    public string EndpointUrl { get; set; } = string.Empty;

    /// <summary>
    ///     Optional failover endpoint URLs for redundancy.
    /// </summary>
    public string[]? FailoverUrls { get; set; }

    /// <summary>
    ///     Optional username for authentication.
    /// </summary>
    public string? Username { get; set; }

    /// <summary>
    ///     Optional password for authentication.
    /// </summary>
    public string? Password { get; set; }

    /// <summary>
    ///     Transport security mode. Defaults to <see cref="Models.SecurityMode.None" />.
    /// </summary>
    public SecurityMode SecurityMode { get; set; } = SecurityMode.None;

    /// <summary>
    ///     Session timeout in seconds. Defaults to 60.
    /// </summary>
    public int SessionTimeoutSeconds { get; set; } = 60;

    /// <summary>
    ///     Whether to automatically accept untrusted server certificates. Defaults to true.
    /// </summary>
    public bool AutoAcceptCertificates { get; set; } = true;

    /// <summary>
    ///     Path to the certificate store. Defaults to <see cref="string.Empty"/>; the
    ///     consuming application configuration factory resolves the canonical path via
    ///     <see cref="ClientStoragePaths.GetPkiPath"/> lazily on first connect, so
    ///     constructing settings — including the throwaway copies built per failover
    ///     attempt — does not touch disk or run the legacy-folder migration probe.
    /// </summary>
    public string CertificateStorePath { get; set; } = string.Empty;

    /// <summary>
    ///     Validates the settings and throws if any required values are missing or invalid.
    /// </summary>
    /// <exception cref="ArgumentException">Thrown when settings are invalid.</exception>
    public void Validate()
    {
        if (string.IsNullOrWhiteSpace(EndpointUrl))
            throw new ArgumentException("EndpointUrl must not be null or empty.", nameof(EndpointUrl));

        if (SessionTimeoutSeconds <= 0)
            throw new ArgumentException("SessionTimeoutSeconds must be greater than zero.",
                nameof(SessionTimeoutSeconds));

        if (SessionTimeoutSeconds > 3600)
            throw new ArgumentException("SessionTimeoutSeconds must not exceed 3600.", nameof(SessionTimeoutSeconds));
    }
}