using MongoDB.Driver;

namespace StellaOps.Authority.Storage.Mongo.Options;

/// <summary>
/// Strongly typed configuration for the StellaOps Authority MongoDB storage layer.
/// </summary>
public sealed class AuthorityMongoOptions
{
    /// <summary>
    /// MongoDB connection string used to bootstrap the client.
    /// </summary>
    public string ConnectionString { get; set; } = string.Empty;

    /// <summary>
    /// Optional override for the database name. When omitted the database name embedded in the connection string is used.
    /// </summary>
    public string? DatabaseName { get; set; }

    /// <summary>
    /// Command timeout applied to MongoDB operations.
    /// </summary>
    public TimeSpan CommandTimeout { get; set; } = TimeSpan.FromSeconds(30);

    /// <summary>
    /// Returns the resolved database name.
    /// </summary>
    public string GetDatabaseName()
    {
        if (!string.IsNullOrWhiteSpace(DatabaseName))
        {
            return DatabaseName.Trim();
        }

        if (!string.IsNullOrWhiteSpace(ConnectionString))
        {
            var url = MongoUrl.Create(ConnectionString);
            if (!string.IsNullOrWhiteSpace(url.DatabaseName))
            {
                return url.DatabaseName;
            }
        }

        return AuthorityMongoDefaults.DefaultDatabaseName;
    }

    /// <summary>
    /// Validates configured values and throws when invalid.
    /// </summary>
    public void EnsureValid()
    {
        if (string.IsNullOrWhiteSpace(ConnectionString))
        {
            throw new InvalidOperationException("Authority Mongo storage requires a connection string.");
        }

        if (CommandTimeout <= TimeSpan.Zero)
        {
            throw new InvalidOperationException("Authority Mongo storage command timeout must be greater than zero.");
        }

        _ = GetDatabaseName();
    }
}
