"""
License Key Generation Service

Generates cryptographically secure license keys with embedded metadata.
"""

import secrets
import hashlib
import base64
import json
import os
from datetime import datetime, timezone, timedelta
from typing import Dict, Any, Optional
from enum import Enum
import logging

logger = logging.getLogger(__name__)


class LicenseType(Enum):
    TRIAL = "trial"
    PROFESSIONAL = "professional"
    ENTERPRISE = "enterprise"


class LicenseKeyGenerator:
    """Generate and validate license keys with embedded metadata"""
    
    # Secret key for HMAC — read from environment, fall back to a dev-only default
    SECRET_KEY = os.getenv("LICENSE_HMAC_SECRET", "rivet-license-secret-dev")
    
    @staticmethod
    def generate_license_key(
        license_type: LicenseType,
        seats: int = 1,
        validity_months: int = 12,
        customer_id: Optional[str] = None
    ) -> Dict[str, Any]:
        """
        Generate a new license key with embedded metadata.
        
        Args:
            license_type: Type of license
            seats: Number of seats/activations allowed
            validity_months: License validity in months
            customer_id: Optional customer identifier
            
        Returns:
            Dict with license_key, metadata, and expiration info
        """
        # Generate unique license ID
        license_id = secrets.token_hex(8).upper()
        
        # Calculate expiration
        issued_at = datetime.now(timezone.utc)
        expires_at = issued_at + timedelta(days=validity_months * 30)
        
        # Create metadata payload
        metadata = {
            "id": license_id,
            "type": license_type.value,
            "seats": seats,
            "issued_at": issued_at.isoformat(),
            "expires_at": expires_at.isoformat(),
            "customer_id": customer_id,
            "version": "1.0"
        }
        
        # Encode metadata
        metadata_json = json.dumps(metadata, separators=(',', ':'))
        metadata_b64 = base64.b64encode(metadata_json.encode()).decode()
        
        # Generate HMAC signature
        signature = LicenseKeyGenerator._generate_signature(metadata_b64)
        
        # Format license key: RIVET-{TYPE}-{ID}-{CHECKSUM}
        type_code = {
            LicenseType.TRIAL: "TRL",
            LicenseType.PROFESSIONAL: "PRO", 
            LicenseType.ENTERPRISE: "ENT"
        }[license_type]
        
        checksum = hashlib.sha256(f"{license_id}{signature}".encode()).hexdigest()[:8].upper()
        license_key = f"RIVET-{type_code}-{license_id}-{checksum}"
        
        logger.info(f"Generated license key: {license_key[:8]}*** (type={license_type.value}, seats={seats})")
        
        return {
            "license_key": license_key,
            "metadata": metadata,
            "signature": signature,
            "expires_at": expires_at.isoformat(),
            "seats": seats,
            "license_type": license_type.value
        }
    
    @staticmethod
    def validate_license_key(license_key: str) -> Dict[str, Any]:
        """
        Validate and decode license key metadata.
        
        Args:
            license_key: License key to validate
            
        Returns:
            Dict with validation result and metadata
            
        Raises:
            ValueError: If license key is invalid
        """
        try:
            # Parse license key format
            parts = license_key.split('-')
            if len(parts) != 4 or parts[0] != "RIVET":
                raise ValueError("Invalid license key format")
            
            prefix, type_code, license_id, checksum = parts
            
            # Validate type code
            type_mapping = {
                "TRL": LicenseType.TRIAL,
                "PRO": LicenseType.PROFESSIONAL,
                "ENT": LicenseType.ENTERPRISE
            }
            
            if type_code not in type_mapping:
                raise ValueError("Invalid license type code")
            
            license_type = type_mapping[type_code]
            
            # For now, return basic validation (full validation would require stored metadata)
            return {
                "valid": True,
                "license_id": license_id,
                "license_type": license_type.value,
                "checksum": checksum,
                "message": "License key format is valid"
            }
            
        except Exception as e:
            logger.warning(f"License key validation failed: {e}")
            return {
                "valid": False,
                "error": str(e),
                "message": "Invalid license key"
            }
    
    @staticmethod
    def _generate_signature(data: str) -> str:
        """Generate HMAC signature for license data"""
        import hmac
        signature = hmac.new(
            LicenseKeyGenerator.SECRET_KEY.encode(),
            data.encode(),
            hashlib.sha256
        ).hexdigest()
        return signature[:16].upper()
    
    @staticmethod
    def generate_trial_license() -> Dict[str, Any]:
        """Generate a 14-day trial license"""
        return LicenseKeyGenerator.generate_license_key(
            license_type=LicenseType.TRIAL,
            seats=1,
            validity_months=0,  # Will be overridden to 14 days
            customer_id=None
        )
    
    @staticmethod
    def generate_professional_license(seats: int = 1, validity_months: int = 12) -> Dict[str, Any]:
        """Generate a professional license"""
        return LicenseKeyGenerator.generate_license_key(
            license_type=LicenseType.PROFESSIONAL,
            seats=seats,
            validity_months=validity_months
        )
    
    @staticmethod
    def generate_enterprise_license(seats: int = 10, validity_months: int = 12) -> Dict[str, Any]:
        """Generate an enterprise license"""
        return LicenseKeyGenerator.generate_license_key(
            license_type=LicenseType.ENTERPRISE,
            seats=seats,
            validity_months=validity_months
        )