#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
日志管理器模块
提供异步日志功能（使用 QueueHandler + QueueListener）
"""
import logging
from logging.handlers import QueueHandler, QueueListener, RotatingFileHandler
import queue
import os
import config
from version import VERSION


class LoggerManager:
    """日志管理器（单例）"""
    _instance = None
    
    def __new__(cls):
        if cls._instance is None:
            cls._instance = super(LoggerManager, cls).__new__(cls)
            cls._instance._initialized = False
        return cls._instance
    
    def __init__(self):
        if self._initialized:
            return
        
        # 私有状态
        self._log_queue = None
        self._queue_listener = None
        self._logger = None
        
        self._initialized = True
    
    # ==================== 状态访问（只读属性）====================
    
    @property
    def logger(self):
        """获取logger对象（只读）"""
        return self._logger
    
    @property
    def log_queue(self):
        """获取日志队列（只读）"""
        return self._log_queue
    
    # ==================== 业务方法 ====================
    
    def init_logging(self, log_level=logging.INFO, log_file=None, max_bytes=None, backup_count=None):
        """
        初始化异步日志系统（使用 QueueHandler + QueueListener）
        
        Args:
            log_level: 日志级别，默认 INFO
            log_file: 日志文件路径，默认使用 config.LOG_FILE
            max_bytes: 单个日志文件最大大小（字节），默认使用 config.LOG_MAX_BYTES
            backup_count: 保留的备份文件数量，默认使用 config.LOG_BACKUP_COUNT
        """
        if log_file is None:
            log_file = config.LOG_FILE
        if max_bytes is None:
            max_bytes = config.LOG_MAX_BYTES
        if backup_count is None:
            backup_count = config.LOG_BACKUP_COUNT
        
        try:
            # 创建日志队列（有界队列，防止内存泄漏；满时自动丢弃旧日志）
            self._log_queue = queue.Queue(maxsize=config.LOG_QUEUE_MAXSIZE)
            
            # 确保日志文件所在的目录存在
            log_dir = os.path.dirname(log_file)
            if log_dir:  # 如果日志路径包含目录
                try:
                    os.makedirs(log_dir, exist_ok=True)
                except Exception as e:
                    print(f"[WARN] 无法创建日志目录 {log_dir}: {e}")
            
            # 尝试创建文件Handler（带日志轮转）
            try:
                file_handler = RotatingFileHandler(
                    log_file,
                    maxBytes=max_bytes,
                    backupCount=backup_count,
                    encoding='utf-8',
                    mode='a'  # 追加模式，确保不覆盖
                )
            except Exception as e:
                # 如果RotatingFileHandler不可用，降级为普通FileHandler
                print(f"[WARN] RotatingFileHandler不可用，使用普通FileHandler: {e}")
                try:
                    file_handler = logging.FileHandler(log_file, encoding='utf-8', mode='a')
                except Exception as e2:
                    # 如果文件Handler创建失败，只使用控制台Handler
                    print(f"[WARN] 无法创建文件Handler，仅使用控制台输出: {e2}")
                    file_handler = None
            
            # 自定义Formatter，包含版本信息
            class CustomFormatter(logging.Formatter):
                """自定义日志格式，包含版本信息和行号"""
                def format(self, record):
                    record.version = VERSION
                    return super().format(record)
            
            # 如果file_handler存在，设置格式和级别
            if file_handler is not None:
                file_handler.setFormatter(CustomFormatter(
                    '%(asctime)s [v%(version)s] [%(levelname)s] %(filename)s:%(lineno)d - %(message)s',
                    datefmt='%Y-%m-%d %H:%M:%S'
                ))
                file_handler.setLevel(log_level)
            
            # 创建控制台Handler（保留原有的print输出）
            console_handler = logging.StreamHandler()
            console_handler.setFormatter(CustomFormatter(
                '[v%(version)s] [%(levelname)s] %(filename)s:%(lineno)d - %(message)s'
            ))
            console_handler.setLevel(log_level)
            
            # 创建QueueListener（后台线程处理日志写入）
            # 如果file_handler为None，只使用console_handler
            handlers = [console_handler]
            if file_handler is not None:
                handlers.append(file_handler)
            
            self._queue_listener = QueueListener(
                self._log_queue, 
                *handlers,
                respect_handler_level=True
            )
            self._queue_listener.start()
            
            # 创建QueueHandler（用于记录日志）
            queue_handler = QueueHandler(self._log_queue)
            
            # 配置根logger
            self._logger = logging.getLogger()
            self._logger.addHandler(queue_handler)
            self._logger.setLevel(log_level)
            
            # 避免日志向上传播到其他logger
            self._logger.propagate = False
            
            # 添加启动标记
            self._logger.info("=" * 60)
            self._logger.info("程序启动 - 日志系统初始化")
            self._logger.info(f"版本: {VERSION}")
            self._logger.info(f"日志文件: {log_file}")
            self._logger.info("=" * 60)
            
            return True
        except Exception as e:
            # 如果日志初始化失败，至少保证程序能运行
            print(f"[ERROR] 日志系统初始化失败: {e}")
            import traceback
            try:
                traceback.print_exc()
            except:
                pass
            return False
    
    def stop_logging(self):
        """停止日志系统（程序退出时调用）"""
        try:
            if self._logger:
                # 确保所有日志都写入
                self._logger.info("程序退出，正在保存日志...")
                import time as std_time
                std_time.sleep(0.5)  # 给一点时间让日志写入
            
            if self._queue_listener:
                self._queue_listener.stop()
            
            if self._logger:
                # 等待队列中的日志处理完成
                if self._log_queue:
                    import time as std_time
                    timeout = 5
                    start = std_time.time()
                    while not self._log_queue.empty() and (std_time.time() - start) < timeout:
                        std_time.sleep(0.1)
            print("[LOG] 日志系统已停止")
        except Exception as e:
            print(f"[ERROR] 停止日志系统失败: {e}")


# 创建全局单例实例
logger_manager = LoggerManager()

# ==================== 向后兼容的函数接口 ====================

def init_logging(log_level=logging.INFO, log_file=None, max_bytes=None, backup_count=None):
    """初始化日志系统（向后兼容接口）"""
    return logger_manager.init_logging(log_level, log_file, max_bytes, backup_count)

def stop_logging():
    """停止日志系统（向后兼容接口）"""
    return logger_manager.stop_logging()

def get_logger():
    """
    获取全局logger对象（向后兼容接口）
    如果日志系统未初始化，返回None（此时可以使用print作为fallback）
    """
    return logger_manager.logger







