"""Post-Quantum Cryptography Precompiled Functions.

This module provides precompiled implementations of post-quantum cryptographic
operations for efficient execution. These functions are optimized for performance
and can be used as building blocks for higher-level cryptographic operations.

Features:
- Precompiled ML-DSA (CRYSTALS-Dilithium) operations
- Precompiled SLH-DSA (SPHINCS+) operations
- Optimized for performance and memory efficiency
- Quantum-resistant cryptographic primitives
"""

import hashlib
import os
from typing import Tuple

from .ml_dsa import ML_DSA, ML_DSA_KeyPair
from .slh_dsa import SLH_DSA, SLH_DSA_KeyPair


def ml_dsa_keygen_precompile(security_level: int = 3) -> ML_DSA_KeyPair:
    """Precompiled ML-DSA key generation function.
    
    This function provides an optimized implementation of ML-DSA key generation
    that can be precompiled for efficient execution.
    
    Args:
        security_level: Security level (2, 3, or 5)
        
    Returns:
        ML_DSA_KeyPair: Generated key pair
        
    Example:
        >>> keypair = ml_dsa_keygen_precompile(3)
        >>> print(f"Public key size: {len(keypair.public_key)} bytes")
    """
    ml_dsa = ML_DSA(security_level=security_level)
    return ml_dsa.generate_keypair()


def ml_dsa_sign_precompile(private_key: bytes, message: bytes, security_level: int = 3) -> bytes:
    """Precompiled ML-DSA signing function.
    
    This function provides an optimized implementation of ML-DSA signing
    that can be precompiled for efficient execution.
    
    Args:
        private_key: Private key bytes
        message: Message to sign
        security_level: Security level used for key generation
        
    Returns:
        bytes: Digital signature
        
    Example:
        >>> signature = ml_dsa_sign_precompile(private_key, b"Hello, World!")
        >>> print(f"Signature size: {len(signature)} bytes")
    """
    ml_dsa = ML_DSA(security_level=security_level)
    return ml_dsa.sign(private_key, message)


def ml_dsa_verify_precompile(public_key: bytes, message: bytes, signature: bytes, security_level: int = 3) -> bool:
    """Precompiled ML-DSA verification function.
    
    This function provides an optimized implementation of ML-DSA signature verification
    that can be precompiled for efficient execution.
    
    Args:
        public_key: Public key bytes
        message: Original message
        signature: Signature to verify
        security_level: Security level used for key generation
        
    Returns:
        bool: True if signature is valid, False otherwise
        
    Example:
        >>> is_valid = ml_dsa_verify_precompile(public_key, b"Hello, World!", signature)
        >>> print(f"Signature valid: {is_valid}")
    """
    ml_dsa = ML_DSA(security_level=security_level)
    return ml_dsa.verify(public_key, message, signature)


def slh_dsa_keygen_precompile(security_level: int = 128) -> SLH_DSA_KeyPair:
    """Precompiled SLH-DSA key generation function.
    
    This function provides an optimized implementation of SLH-DSA key generation
    that can be precompiled for efficient execution.
    
    Args:
        security_level: Security level (128, 192, or 256)
        
    Returns:
        SLH_DSA_KeyPair: Generated key pair
        
    Example:
        >>> keypair = slh_dsa_keygen_precompile(128)
        >>> print(f"Public key size: {len(keypair.public_key)} bytes")
    """
    slh_dsa = SLH_DSA(security_level=security_level)
    return slh_dsa.generate_keypair()


def slh_dsa_sign_precompile(private_key: bytes, message: bytes, security_level: int = 128) -> bytes:
    """Precompiled SLH-DSA signing function.
    
    This function provides an optimized implementation of SLH-DSA signing
    that can be precompiled for efficient execution.
    
    Args:
        private_key: Private key bytes
        message: Message to sign
        security_level: Security level used for key generation
        
    Returns:
        bytes: Digital signature
        
    Example:
        >>> signature = slh_dsa_sign_precompile(private_key, b"Hello, World!")
        >>> print(f"Signature size: {len(signature)} bytes")
    """
    slh_dsa = SLH_DSA(security_level=security_level)
    return slh_dsa.sign(private_key, message)


def slh_dsa_verify_precompile(public_key: bytes, message: bytes, signature: bytes, security_level: int = 128) -> bool:
    """Precompiled SLH-DSA verification function.
    
    This function provides an optimized implementation of SLH-DSA signature verification
    that can be precompiled for efficient execution.
    
    Args:
        public_key: Public key bytes
        message: Original message
        signature: Signature to verify
        security_level: Security level used for key generation
        
    Returns:
        bool: True if signature is valid, False otherwise
        
    Example:
        >>> is_valid = slh_dsa_verify_precompile(public_key, b"Hello, World!", signature)
        >>> print(f"Signature valid: {is_valid}")
    """
    slh_dsa = SLH_DSA(security_level=security_level)
    return slh_dsa.verify(public_key, message, signature)


# Utility functions for cryptographic operations

def generate_quantum_resistant_hash(data: bytes, output_size: int = 32) -> bytes:
    """Generate a quantum-resistant hash using SHAKE-256.
    
    Args:
        data: Input data to hash
        output_size: Desired output size in bytes
        
    Returns:
        bytes: Hash output
    """
    return hashlib.shake_256(data).digest(output_size)


def generate_secure_random_bytes(size: int) -> bytes:
    """Generate cryptographically secure random bytes.
    
    Args:
        size: Number of bytes to generate
        
    Returns:
        bytes: Random bytes
    """
    return os.urandom(size)


# Precompiled parameter sets for quick reference
ML_DSA_PARAMETERS = {
    2: {"name": "Dilithium2", "security_bits": 128, "recommended": True},
    3: {"name": "Dilithium3", "security_bits": 192, "recommended": True},
    5: {"name": "Dilithium5", "security_bits": 256, "recommended": True},
}

SLH_DSA_PARAMETERS = {
    128: {"name": "SPHINCS+-128", "security_bits": 128, "recommended": True},
    192: {"name": "SPHINCS+-192", "security_bits": 192, "recommended": True},
    256: {"name": "SPHINCS+-256", "security_bits": 256, "recommended": True},
}