#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
日志管理模块
提供标准化的日志记录功能
"""

import logging
import os
import re
from logging.handlers import RotatingFileHandler
from datetime import datetime
import threading

# 全局日志配置
_loggers = {}
_logger_lock = threading.Lock()


class ColoredFormatter(logging.Formatter):
    """带颜色的日志格式化器（用于控制台）"""

    # ANSI颜色代码
    COLORS = {
        'DEBUG': '\033[36m',      # 青色
        'INFO': '\033[32m',       # 绿色
        'WARNING': '\033[33m',    # 黄色
        'ERROR': '\033[31m',      # 红色
        'CRITICAL': '\033[35m',   # 紫色
    }
    RESET = '\033[0m'

    def format(self, record):
        """格式化日志记录"""
        # 添加颜色
        levelname = record.levelname
        if levelname in self.COLORS:
            record.levelname = f"{self.COLORS[levelname]}{levelname}{self.RESET}"

        # 格式化
        result = super().format(record)

        # 恢复原始levelname（避免影响其他handler）
        record.levelname = levelname

        return result


class SensitiveDataFilter(logging.Filter):
    """对日志中的敏感字段做统一脱敏处理。"""

    _EMAIL_RE = re.compile(r"\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}\b")
    _PAIR_PATTERNS = (
        (re.compile(r"(?i)\b(password|passwd|pwd)\s*[:=]\s*([^,\s]+)"), r"\1=[REDACTED]"),
        (re.compile(r"(?i)\b(token|csrf_token|session|authorization)\s*[:=]\s*([^,\s]+)"), r"\1=[REDACTED]"),
        (re.compile(r"(?i)\b(user_id|admin_id|token_id)\s*=\s*\d+\b"), r"\1=[MASKED]"),
    )

    def filter(self, record: logging.LogRecord) -> bool:
        try:
            message = record.getMessage()
            sanitized = self._EMAIL_RE.sub("[REDACTED_EMAIL]", message)
            for pattern, replacement in self._PAIR_PATTERNS:
                sanitized = pattern.sub(replacement, sanitized)
            if sanitized != message:
                record.msg = sanitized
                record.args = ()
        except Exception:
            # 日志过滤异常不应影响业务日志输出
            pass
        return True


def setup_logger(name='app', level=None, log_file=None, max_bytes=10*1024*1024, backup_count=5):
    """
    设置日志记录器

    Args:
        name: 日志器名称
        level: 日志级别（DEBUG, INFO, WARNING, ERROR, CRITICAL）
        log_file: 日志文件路径
        max_bytes: 日志文件最大大小（字节）
        backup_count: 保留的备份文件数量

    Returns:
        logging.Logger: 配置好的日志器
    """
    with _logger_lock:
        # 如果已经存在，直接返回
        if name in _loggers:
            return _loggers[name]

        # 创建日志器
        logger = logging.getLogger(name)

        # 设置日志级别
        if level is None:
            level = os.environ.get('LOG_LEVEL', 'INFO')
        logger.setLevel(getattr(logging, level.upper()))

        # 清除已有的处理器（避免重复）
        logger.handlers.clear()
        logger.filters.clear()

        # 全局敏感日志脱敏（默认开启，可通过 LOG_REDACT_SENSITIVE=0 关闭）
        redact_enabled = str(os.environ.get("LOG_REDACT_SENSITIVE", "1")).strip().lower() in {
            "1",
            "true",
            "yes",
            "on",
        }
        if redact_enabled:
            logger.addFilter(SensitiveDataFilter())

        # 日志格式
        detailed_formatter = logging.Formatter(
            '[%(asctime)s] [%(name)s] [%(levelname)s] [%(filename)s:%(lineno)d] - %(message)s',
            datefmt='%Y-%m-%d %H:%M:%S'
        )

        simple_formatter = logging.Formatter(
            '[%(asctime)s] [%(levelname)s] %(message)s',
            datefmt='%Y-%m-%d %H:%M:%S'
        )

        colored_formatter = ColoredFormatter(
            '[%(asctime)s] [%(levelname)s] %(message)s',
            datefmt='%Y-%m-%d %H:%M:%S'
        )

        # 控制台处理器（带颜色）
        console_handler = logging.StreamHandler()
        console_handler.setLevel(logging.INFO)
        console_handler.setFormatter(colored_formatter)
        logger.addHandler(console_handler)

        # 文件处理器（如果指定了文件路径）
        if log_file:
            # 确保日志目录存在
            log_dir = os.path.dirname(log_file)
            if log_dir and not os.path.exists(log_dir):
                os.makedirs(log_dir, exist_ok=True)

            # 主日志文件（详细格式）
            file_handler = RotatingFileHandler(
                log_file,
                maxBytes=max_bytes,
                backupCount=backup_count,
                encoding='utf-8'
            )
            file_handler.setLevel(logging.DEBUG)
            file_handler.setFormatter(detailed_formatter)
            logger.addHandler(file_handler)

            # 错误日志文件（仅记录WARNING及以上）
            error_file = log_file.replace('.log', '_error.log')
            error_handler = RotatingFileHandler(
                error_file,
                maxBytes=max_bytes,
                backupCount=backup_count,
                encoding='utf-8'
            )
            error_handler.setLevel(logging.WARNING)
            error_handler.setFormatter(detailed_formatter)
            logger.addHandler(error_handler)

        # 防止日志向上传播（避免重复）
        logger.propagate = False

        # 缓存日志器
        _loggers[name] = logger

        return logger


def get_logger(name='app'):
    """
    获取日志记录器

    Args:
        name: 日志器名称

    Returns:
        logging.Logger: 日志器实例
    """
    if name in _loggers:
        return _loggers[name]
    else:
        # 如果不存在，创建一个默认的
        return setup_logger(name)


class LoggerAdapter:
    """日志适配器，提供便捷的日志记录方法"""

    def __init__(self, logger_name='app', context=None):
        """
        初始化日志适配器

        Args:
            logger_name: 日志器名称
            context: 上下文信息（如用户ID、账号ID等）
        """
        self.logger = get_logger(logger_name)
        self.context = context or {}

    def _format_message(self, message):
        """格式化消息，添加上下文信息"""
        if self.context:
            context_str = ' '.join([f"[{k}={v}]" for k, v in self.context.items()])
            return f"{context_str} {message}"
        return message

    def debug(self, message):
        """记录调试信息"""
        self.logger.debug(self._format_message(message))

    def info(self, message):
        """记录普通信息"""
        self.logger.info(self._format_message(message))

    def warning(self, message):
        """记录警告信息"""
        self.logger.warning(self._format_message(message))

    def error(self, message, exc_info=False):
        """记录错误信息"""
        self.logger.error(self._format_message(message), exc_info=exc_info)

    def critical(self, message, exc_info=False):
        """记录严重错误信息"""
        self.logger.critical(self._format_message(message), exc_info=exc_info)

    def exception(self, message):
        """记录异常信息（自动包含堆栈跟踪）"""
        self.logger.exception(self._format_message(message))


class AuditLogger:
    """审计日志记录器（用于记录关键操作）"""

    def __init__(self, log_file='logs/audit.log'):
        """初始化审计日志"""
        self.logger = setup_logger('audit', level='INFO', log_file=log_file)

    def log_user_login(self, user_id, username, ip_address, success=True):
        """记录用户登录"""
        status = "成功" if success else "失败"
        self.logger.info(f"用户登录{status}: user_id={user_id}, username={username}, ip={ip_address}")

    def log_admin_login(self, username, ip_address, success=True):
        """记录管理员登录"""
        status = "成功" if success else "失败"
        self.logger.info(f"管理员登录{status}: username={username}, ip={ip_address}")

    def log_user_created(self, user_id, username, created_by=None):
        """记录用户创建"""
        self.logger.info(f"用户创建: user_id={user_id}, username={username}, created_by={created_by}")

    def log_user_deleted(self, user_id, username, deleted_by):
        """记录用户删除"""
        self.logger.warning(f"用户删除: user_id={user_id}, username={username}, deleted_by={deleted_by}")

    def log_password_reset(self, user_id, username, reset_by):
        """记录密码重置"""
        self.logger.warning(f"密码重置: user_id={user_id}, username={username}, reset_by={reset_by}")

    def log_config_change(self, config_name, old_value, new_value, changed_by):
        """记录配置修改"""
        self.logger.warning(f"配置修改: {config_name} 从 {old_value} 改为 {new_value}, changed_by={changed_by}")

    def log_security_event(self, event_type, description, ip_address=None):
        """记录安全事件"""
        self.logger.warning(f"安全事件 [{event_type}]: {description}, ip={ip_address}")


# 全局审计日志实例
audit_logger = AuditLogger()


# 辅助函数
def log_exception(logger, message="发生异常"):
    """记录异常（包含堆栈跟踪）"""
    if isinstance(logger, str):
        logger = get_logger(logger)
    logger.exception(message)


def log_performance(logger, operation, duration_ms, threshold_ms=1000):
    """记录性能信息"""
    if isinstance(logger, str):
        logger = get_logger(logger)

    if duration_ms > threshold_ms:
        logger.warning(f"性能警告: {operation} 耗时 {duration_ms}ms (阈值: {threshold_ms}ms)")
    else:
        logger.debug(f"性能: {operation} 耗时 {duration_ms}ms")


# 初始化默认日志器
def init_logging(log_level='INFO', log_file='logs/app.log'):
    """
    初始化日志系统

    Args:
        log_level: 日志级别
        log_file: 日志文件路径
    """
    # 创建主应用日志器
    setup_logger('app', level=log_level, log_file=log_file)

    # 创建数据库日志器
    setup_logger('database', level=log_level, log_file='logs/database.log')

    # 创建自动化日志器
    setup_logger('automation', level=log_level, log_file='logs/automation.log')

    # 创建审计日志器（已在AuditLogger中创建）

    try:
        get_logger('app').info("[OK] 日志系统初始化完成")
    except Exception:
        print("[OK] 日志系统初始化完成")


if __name__ == '__main__':
    # 测试日志系统
    init_logging(log_level='DEBUG')

    logger = get_logger('app')
    logger.debug("这是调试信息")
    logger.info("这是普通信息")
    logger.warning("这是警告信息")
    logger.error("这是错误信息")
    logger.critical("这是严重错误信息")

    # 测试上下文日志
    adapter = LoggerAdapter('app', {'user_id': 123, 'username': 'test'})
    adapter.info("用户操作日志")

    # 测试审计日志
    audit_logger.log_user_login(123, 'test_user', '127.0.0.1', success=True)
    audit_logger.log_security_event('LOGIN_ATTEMPT', '多次登录失败', '192.168.1.1')

    print("\n日志测试完成，请检查 logs/ 目录")
