"""
Logging Utilities

v2.0 Critical Fix #5: Privacy-first comprehensive logging system.

Privacy Policy:
- NEVER log API keys or credentials
- NEVER log message content (user or assistant messages)
- Only log metadata, events, errors, and system information
"""

import logging
import os
import re
from logging.handlers import RotatingFileHandler
from pathlib import Path
from typing import Any


# Sensitive patterns to redact
SENSITIVE_PATTERNS = [
    (re.compile(r'(api[_-]?key["\s:=]+)([a-zA-Z0-9_-]+)', re.IGNORECASE), r'\1***REDACTED***'),
    (re.compile(r'(bearer\s+)([a-zA-Z0-9_-]+)', re.IGNORECASE), r'\1***REDACTED***'),
    (re.compile(r'(password["\s:=]+)([^\s]+)', re.IGNORECASE), r'\1***REDACTED***'),
    (re.compile(r'(token["\s:=]+)([a-zA-Z0-9_-]+)', re.IGNORECASE), r'\1***REDACTED***'),
]


def redact_sensitive_info(message: str) -> str:
    """
    Redact sensitive information from log messages.

    Args:
        message: Log message that may contain sensitive data

    Returns:
        Message with sensitive data redacted
    """
    for pattern, replacement in SENSITIVE_PATTERNS:
        message = pattern.sub(replacement, message)
    return message


class PrivacyFilter(logging.Filter):
    """
    Logging filter that redacts sensitive information.

    v2.0 Critical: Ensures no API keys or credentials are logged.
    """

    def filter(self, record: logging.LogRecord) -> bool:
        # Redact sensitive info from message
        if isinstance(record.msg, str):
            record.msg = redact_sensitive_info(record.msg)

        # Redact sensitive info from args
        if record.args:
            record.args = tuple(
                redact_sensitive_info(str(arg)) if isinstance(arg, str) else arg
                for arg in record.args
            )

        return True


def setup_logging(
    log_file: str | Path,
    log_level: str = "INFO",
    max_size_mb: int = 5,
    backup_count: int = 3,
) -> logging.Logger:
    """
    Set up privacy-first logging for HoneyDB MCP CLI.

    v2.0 Critical Fix #5: Privacy-first comprehensive logging.

    Args:
        log_file: Path to log file
        log_level: Logging level (DEBUG, INFO, WARNING, ERROR)
        max_size_mb: Maximum log file size in MB before rotation
        backup_count: Number of backup files to keep

    Returns:
        Configured logger instance
    """
    # Expand paths
    log_file = Path(log_file).expanduser()
    log_file.parent.mkdir(parents=True, exist_ok=True)

    # Create logger
    logger = logging.getLogger("honeydb_ai")
    logger.setLevel(getattr(logging, log_level.upper()))

    # Remove existing handlers to avoid duplicates
    logger.handlers.clear()

    # Create rotating file handler
    file_handler = RotatingFileHandler(
        log_file,
        maxBytes=max_size_mb * 1024 * 1024,
        backupCount=backup_count,
        encoding='utf-8'
    )
    file_handler.setLevel(getattr(logging, log_level.upper()))

    # Create formatter
    formatter = logging.Formatter(
        fmt='%(asctime)s - %(name)s - %(levelname)s - %(funcName)s:%(lineno)d - %(message)s',
        datefmt='%Y-%m-%d %H:%M:%S'
    )
    file_handler.setFormatter(formatter)

    # Add privacy filter
    file_handler.addFilter(PrivacyFilter())

    # Add handler to logger
    logger.addHandler(file_handler)

    # Prevent propagation to root logger
    logger.propagate = False

    logger.info("=" * 80)
    logger.info("HoneyDB MCP CLI logging initialized")
    logger.info(f"Log level: {log_level}")
    logger.info(f"Log file: {log_file}")
    logger.info("=" * 80)

    return logger


def log_event(logger: logging.Logger, event_type: str, data: dict[str, Any]) -> None:
    """
    Log an event with metadata.

    Privacy-Safe: Only logs event type and non-sensitive metadata.

    Args:
        logger: Logger instance
        event_type: Type of event (e.g., "tool_call", "session_saved")
        data: Event metadata (should not contain sensitive data)
    """
    # Filter out sensitive keys from data
    safe_data = {
        k: v for k, v in data.items()
        if k not in ['api_key', 'password', 'token', 'content', 'message', 'messages']
    }

    logger.info(f"Event: {event_type} | Data: {safe_data}")


def log_llm_request(logger: logging.Logger, provider: str, model: str, message_count: int) -> None:
    """
    Log an LLM request (metadata only).

    Privacy-Safe: Only logs provider, model, and message count.
    NEVER logs message content.

    Args:
        logger: Logger instance
        provider: LLM provider name
        model: Model identifier
        message_count: Number of messages in request
    """
    logger.info(f"LLM Request | Provider: {provider} | Model: {model} | Messages: {message_count}")


def log_llm_response(
    logger: logging.Logger,
    provider: str,
    model: str,
    success: bool,
    duration_ms: float | None = None,
    error: str | None = None
) -> None:
    """
    Log an LLM response (metadata only).

    Privacy-Safe: Only logs provider, model, success status, and duration.
    NEVER logs response content.

    Args:
        logger: Logger instance
        provider: LLM provider name
        model: Model identifier
        success: Whether request succeeded
        duration_ms: Request duration in milliseconds
        error: Error message if request failed
    """
    status = "Success" if success else "Failed"
    duration_str = f" | Duration: {duration_ms:.0f}ms" if duration_ms else ""
    error_str = f" | Error: {error}" if error else ""

    logger.info(f"LLM Response | Provider: {provider} | Model: {model} | Status: {status}{duration_str}{error_str}")


def log_session_operation(logger: logging.Logger, operation: str, session_id: str, success: bool, error: str | None = None) -> None:
    """
    Log a session operation.

    Privacy-Safe: Only logs operation type, session ID, and status.

    Args:
        logger: Logger instance
        operation: Operation type (e.g., "save", "load", "delete")
        session_id: Session identifier
        success: Whether operation succeeded
        error: Error message if operation failed
    """
    status = "Success" if success else "Failed"
    error_str = f" | Error: {error}" if error else ""

    logger.info(f"Session {operation.title()} | ID: {session_id} | Status: {status}{error_str}")


def log_config_operation(logger: logging.Logger, operation: str, success: bool, error: str | None = None) -> None:
    """
    Log a configuration operation.

    Privacy-Safe: Only logs operation type and status.

    Args:
        logger: Logger instance
        operation: Operation type (e.g., "load", "save", "reload")
        success: Whether operation succeeded
        error: Error message if operation failed
    """
    status = "Success" if success else "Failed"
    error_str = f" | Error: {error}" if error else ""

    logger.info(f"Config {operation.title()} | Status: {status}{error_str}")


def get_logger() -> logging.Logger:
    """
    Get the HoneyDB MCP CLI logger instance.

    Returns:
        Logger instance (must be initialized with setup_logging first)
    """
    return logging.getLogger("honeydb_ai")
