using System.Text.Json.Serialization;

namespace NATS.Server.Auth.Jwt;

/// <summary>
/// Represents the claims in a NATS account JWT.
/// Contains standard JWT fields (sub, iss, iat, exp) and a NATS-specific nested object
/// with account limits, signing keys, and revocations.
/// </summary>
/// <remarks>
/// Reference: github.com/nats-io/jwt/v2 — AccountClaims, Account, OperatorLimits types
/// </remarks>
public sealed class AccountClaims
{
    /// <summary>Subject — the account's NKey public key.</summary>
    [JsonPropertyName("sub")]
    public string? Subject { get; set; }

    /// <summary>Issuer — the operator or signing key that issued this JWT.</summary>
    [JsonPropertyName("iss")]
    public string? Issuer { get; set; }

    /// <summary>Issued-at time as Unix epoch seconds.</summary>
    [JsonPropertyName("iat")]
    public long IssuedAt { get; set; }

    /// <summary>Expiration time as Unix epoch seconds. 0 means no expiry.</summary>
    [JsonPropertyName("exp")]
    public long Expires { get; set; }

    /// <summary>Human-readable name for the account.</summary>
    [JsonPropertyName("name")]
    public string? Name { get; set; }

    /// <summary>NATS-specific account claims.</summary>
    [JsonPropertyName("nats")]
    public AccountNats? Nats { get; set; }
}

/// <summary>
/// NATS-specific portion of account JWT claims.
/// Contains limits, signing keys, and user revocations.
/// </summary>
public sealed class AccountNats
{
    /// <summary>Account resource limits.</summary>
    [JsonPropertyName("limits")]
    public AccountLimits? Limits { get; set; }

    /// <summary>JetStream entitlement limits/tier for this account.</summary>
    [JsonPropertyName("jetstream")]
    public AccountJetStreamLimits? JetStream { get; set; }

    /// <summary>NKey public keys authorized to sign user JWTs for this account.</summary>
    [JsonPropertyName("signing_keys")]
    public string[]? SigningKeys { get; set; }

    /// <summary>
    /// Map of revoked user NKey public keys to the Unix epoch time of revocation.
    /// Any user JWT issued before the revocation time is considered revoked.
    /// </summary>
    [JsonPropertyName("revocations")]
    public Dictionary<string, long>? Revocations { get; set; }

    /// <summary>Tags associated with this account.</summary>
    [JsonPropertyName("tags")]
    public string[]? Tags { get; set; }

    /// <summary>Claim type (e.g., "account").</summary>
    [JsonPropertyName("type")]
    public string? Type { get; set; }

    /// <summary>Claim version.</summary>
    [JsonPropertyName("version")]
    public int Version { get; set; }
}

/// <summary>
/// Resource limits for a NATS account. A value of -1 means unlimited.
/// </summary>
public sealed class AccountLimits
{
    /// <summary>Maximum number of connections. -1 means unlimited.</summary>
    [JsonPropertyName("conn")]
    public long MaxConnections { get; set; }

    /// <summary>Maximum number of subscriptions. -1 means unlimited.</summary>
    [JsonPropertyName("subs")]
    public long MaxSubscriptions { get; set; }

    /// <summary>Maximum payload size in bytes. -1 means unlimited.</summary>
    [JsonPropertyName("payload")]
    public long MaxPayload { get; set; }

    /// <summary>Maximum data transfer in bytes. -1 means unlimited.</summary>
    [JsonPropertyName("data")]
    public long MaxData { get; set; }
}

public sealed class AccountJetStreamLimits
{
    [JsonPropertyName("max_streams")]
    public int MaxStreams { get; set; }

    [JsonPropertyName("tier")]
    public string? Tier { get; set; }
}
