"""Input validation utilities for code analyzer endpoints."""
import re
from typing import List, Optional

# Safe patterns for various inputs
_SAFE_EXT_PATTERN = re.compile(r'^[a-zA-Z0-9]{1,10}$')
_SAFE_DIR_PATTERN = re.compile(r'^[a-zA-Z0-9_\-.*]+$')
_SAFE_CONFIG_PATTERN = re.compile(r'^[a-zA-Z0-9/_\-.:]+$')


def sanitize_extensions(extensions: List[str]) -> List[str]:
    """Sanitize file extensions to prevent injection attacks.
    
    Args:
        extensions: List of file extensions to sanitize
        
    Returns:
        List of sanitized extensions
    """
    safe = []
    for ext in extensions:
        ext = ext.strip().lstrip('.')
        if _SAFE_EXT_PATTERN.match(ext):
            safe.append(ext)
    return safe


def sanitize_excluded_dirs(dirs: List[str], max_count: int = 100) -> List[str]:
    """Sanitize excluded directory names.
    
    Args:
        dirs: List of directory names to exclude
        max_count: Maximum number of directories allowed
        
    Returns:
        List of sanitized directory names
        
    Raises:
        ValueError: If too many directories provided
    """
    if len(dirs) > max_count:
        raise ValueError(f"Too many excluded directories (max {max_count})")
    
    safe = []
    for d in dirs:
        d = d.strip()
        if _SAFE_DIR_PATTERN.match(d):
            safe.append(d)
    return safe


def validate_config(config: Optional[str]) -> Optional[str]:
    """Validate scanner config parameter.
    
    Args:
        config: scanner config string
        
    Returns:
        Validated config or None
        
    Raises:
        ValueError: If config is invalid
    """
    if config is None:
        return None
    
    config = config.strip()
    if not config:
        return None
    
    # Allow registry paths (p/*, r/*), URLs, and safe local paths
    if config.startswith(('p/', 'r/', 'http://', 'https://', 'auto')):
        return config
    
    if not _SAFE_CONFIG_PATTERN.match(config):
        raise ValueError(f"Invalid config format: {config}")
    
    return config
