# -*- coding: utf-8 -*-
"""Location: ./tests/load/generators/tokens.py
Copyright 2026
SPDX-License-Identifier: Apache-2.0
Authors: Mihai Criveti

API token generator for load testing.
"""

import random
import secrets
import uuid
from datetime import datetime, timedelta
from typing import Generator, List

from mcpgateway.db import EmailApiToken

from ..utils.distributions import exponential_decay_temporal, normal_distribution
from .base import BaseGenerator


class TokenGenerator(BaseGenerator):
    """Generate EmailApiToken records with realistic distribution."""

    def get_count(self) -> int:
        """Get total number of tokens to generate."""
        user_count = self.get_scale_config("users", 100)
        avg_tokens = self.get_scale_config("tokens_per_user_avg", 5)
        return int(user_count * avg_tokens)

    def get_dependencies(self) -> List[str]:
        """Tokens depend on users."""
        return ["UserGenerator"]

    def generate(self) -> Generator[EmailApiToken, None, None]:
        """Generate API token records.

        Yields:
            EmailApiToken instances
        """
        user_count = self.get_scale_config("users", 100)
        min_tokens = self.get_scale_config("tokens_per_user_min", 1)
        max_tokens = self.get_scale_config("tokens_per_user_max", 10)
        avg_tokens = self.get_scale_config("tokens_per_user_avg", 5)
        active_percent = self.get_scale_config("tokens_active_percent", 90)

        # Get temporal distribution
        start_date = datetime.fromisoformat(self.config.get("temporal", {}).get("start_date", "2023-01-01"))
        end_date = datetime.fromisoformat(self.config.get("temporal", {}).get("end_date", datetime.now().isoformat()))
        recent_percent = self.config.get("temporal", {}).get("recent_data_percent", 80) / 100

        # Generate tokens per user using normal distribution
        tokens_per_user = normal_distribution(user_count, min_tokens, max_tokens, avg_tokens)
        total_tokens = sum(tokens_per_user)

        timestamps = exponential_decay_temporal(total_tokens, start_date, end_date, recent_percent)

        token_idx = 0

        for user_i in range(user_count):
            user_email = f"user{user_i+1}@{self.email_domain}"
            num_tokens = tokens_per_user[user_i]

            for j in range(num_tokens):
                token_id = str(uuid.uuid4())
                token_value = secrets.token_urlsafe(32)
                is_active = random.random() < (active_percent / 100)

                # Random scopes
                scopes = random.sample(
                    ["tools:read", "tools:write", "resources:read", "resources:write",
                     "prompts:read", "prompts:write", "servers:read", "servers:write"],
                    k=random.randint(1, 4)
                )

                # Token expires in 1-365 days
                expires_days = random.randint(1, 365)
                expires_at = timestamps[token_idx] + timedelta(days=expires_days)

                token = EmailApiToken(
                    id=token_id,
                    name=f"Token {j+1} for {user_email}",
                    description=self.faker.sentence(),
                    user_email=user_email,
                    jti=str(uuid.uuid4()),  # JWT ID
                    token_hash=token_value,  # In production this would be hashed
                    resource_scopes=scopes,
                    is_active=is_active,
                    created_at=timestamps[token_idx],
                    expires_at=expires_at,
                    last_used=None,
                )

                token_idx += 1
                yield token