using System;
using System.Collections.Generic;

namespace StellaOps.Auth.Abstractions;

/// <summary>
/// Canonical scope names supported by StellaOps services.
/// </summary>
public static class StellaOpsScopes
{
    /// <summary>
    /// Scope required to trigger Feedser jobs.
    /// </summary>
    public const string FeedserJobsTrigger = "feedser.jobs.trigger";

    /// <summary>
    /// Scope required to manage Feedser merge operations.
    /// </summary>
    public const string FeedserMerge = "feedser.merge";

    /// <summary>
    /// Scope granting administrative access to Authority user management.
    /// </summary>
    public const string AuthorityUsersManage = "authority.users.manage";

    /// <summary>
    /// Scope granting administrative access to Authority client registrations.
    /// </summary>
    public const string AuthorityClientsManage = "authority.clients.manage";

    /// <summary>
    /// Scope granting read-only access to Authority audit logs.
    /// </summary>
    public const string AuthorityAuditRead = "authority.audit.read";

    /// <summary>
    /// Synthetic scope representing trusted network bypass.
    /// </summary>
    public const string Bypass = "stellaops.bypass";

    private static readonly HashSet<string> KnownScopes = new(StringComparer.OrdinalIgnoreCase)
    {
        FeedserJobsTrigger,
        FeedserMerge,
        AuthorityUsersManage,
        AuthorityClientsManage,
        AuthorityAuditRead,
        Bypass
    };

    /// <summary>
    /// Normalises a scope string (trim/convert to lower case).
    /// </summary>
    /// <param name="scope">Scope raw value.</param>
    /// <returns>Normalised scope or <c>null</c> when the input is blank.</returns>
    public static string? Normalize(string? scope)
    {
        if (string.IsNullOrWhiteSpace(scope))
        {
            return null;
        }

        return scope.Trim().ToLowerInvariant();
    }

    /// <summary>
    /// Checks whether the provided scope is registered as a built-in StellaOps scope.
    /// </summary>
    public static bool IsKnown(string scope)
    {
        ArgumentNullException.ThrowIfNull(scope);
        return KnownScopes.Contains(scope);
    }

    /// <summary>
    /// Returns the full set of built-in scopes.
    /// </summary>
    public static IReadOnlyCollection<string> All => KnownScopes;
}
