from __future__ import annotations

"""Utilities to validate licenses and gate features."""

from dataclasses import dataclass
from typing import Callable, Optional

from .manager import SubscriptionManager


class LicenseError(PermissionError):
    """Raised when a feature access is denied."""


@dataclass
class LicenseValidator:
    """Validate whether a manager is allowed to access specific capabilities."""

    manager: SubscriptionManager

    def ensure_invasive_tests_allowed(self) -> None:
        if not self.manager.can_use_invasive_tests():
            raise LicenseError("Invasive tests require a PRO subscription or higher.")

    def ensure_html_export_allowed(self) -> None:
        if not self.manager.can_export_html():
            raise LicenseError("HTML export is only available for PRO subscriptions or higher.")

    def ensure_api_allowed(self) -> None:
        if not self.manager.can_use_api():
            raise LicenseError("API access is reserved for enterprise subscriptions.")


class FeatureGate:
    """Helper around a validator to guard functionality."""

    def __init__(self, validator: LicenseValidator):
        self._validator = validator

    def require(self, check: Callable[[LicenseValidator], None], fallback: Optional[Callable[[], None]] = None) -> Callable[[Callable[..., None]], Callable[..., None]]:
        """Decorator to enforce license checks before executing a function."""

        def decorator(func: Callable[..., None]) -> Callable[..., None]:
            def wrapped(*args, **kwargs):
                try:
                    check(self._validator)
                except LicenseError:
                    if fallback:
                        fallback()
                    else:
                        raise
                else:
                    return func(*args, **kwargs)

            return wrapped

        return decorator
