# Copyright (c) 2026 MergeGuide, Inc. All rights reserved.
# SPDX-License-Identifier: Proprietary
"""Rate limiting tier configuration.

Defines request limits per billing tier with burst allowances.
Tiers are designed to scale from free users to enterprise customers.

Tier Limits (requests per minute):
    - free: 60 req/min (1 req/sec average)
    - trial: 120 req/min (2 req/sec average)
    - team: 300 req/min (5 req/sec average)
    - enterprise: 1000 req/min (~17 req/sec average)

Burst Factor:
    Each tier has a burst allowance that permits short traffic spikes.
    The burst limit = base_limit * burst_factor.
"""

from dataclasses import dataclass
from typing import Literal

# Type alias for supported billing tiers
BillingTier = Literal["free", "trial", "team", "enterprise"]

# Default tier when billing tier is unknown or not set
DEFAULT_TIER: BillingTier = "free"


@dataclass(frozen=True)
class TierConfig:
    """Configuration for a single billing tier's rate limits.

    Attributes:
        requests_per_minute: Base request limit per minute window.
        burst_factor: Multiplier for burst capacity (e.g., 1.5 = 50% burst).
    """

    requests_per_minute: int
    burst_factor: float

    @property
    def burst_limit(self) -> int:
        """Calculate the maximum requests allowed including burst.

        Returns:
            Integer burst limit (base limit * burst factor, rounded down).
        """
        return int(self.requests_per_minute * self.burst_factor)


# Tier configuration mapping
# These values balance fair usage with operational headroom
TIER_LIMITS: dict[BillingTier, TierConfig] = {
    "free": TierConfig(
        requests_per_minute=60,
        burst_factor=1.5,  # 90 max burst
    ),
    "trial": TierConfig(
        requests_per_minute=120,
        burst_factor=1.5,  # 180 max burst
    ),
    "team": TierConfig(
        requests_per_minute=300,
        burst_factor=1.2,  # 360 max burst
    ),
    "enterprise": TierConfig(
        requests_per_minute=1000,
        burst_factor=1.5,  # 1500 max burst
    ),
}


def get_tier_config(tier: str) -> TierConfig:
    """Get the rate limit configuration for a billing tier.

    Args:
        tier: The billing tier name (free, trial, team, enterprise).
            Unknown tiers fall back to the free tier limits.

    Returns:
        TierConfig with the rate limit settings for this tier.
    """
    if tier in TIER_LIMITS:
        return TIER_LIMITS[tier]  # type: ignore[literal-required]
    return TIER_LIMITS[DEFAULT_TIER]


def get_limit_for_tier(tier: str, use_burst: bool = False) -> int:
    """Get the request limit for a tier.

    Args:
        tier: The billing tier name.
        use_burst: If True, return burst limit; otherwise return base limit.

    Returns:
        The applicable request limit per minute.
    """
    config = get_tier_config(tier)
    return config.burst_limit if use_burst else config.requests_per_minute
