# -*- coding: utf-8 -*-
"""
logger.py — 通用日志配置

功能：
  - 统一配置 logging，输出到控制台 + 文件
  - 文件日志按大小轮转（单文件 1MB，保留 3 份）
  - 各模块通过 get_logger(__name__) 获取子 logger

用法：
  from utils.logger import get_logger
  logger = get_logger(__name__)
  logger.info("...")
  logger.exception("...")  # 自动带堆栈
"""

import logging
from logging.handlers import RotatingFileHandler
from pathlib import Path

# 日志根 logger 名称
ROOT_LOGGER_NAME = "troubleshoot"

# 日志文件位置：与本文件同级的 ../logs/app.log
_LOG_DIR = Path(__file__).resolve().parent.parent / "logs"
_LOG_FILE = _LOG_DIR / "app.log"

# 日志格式
_LOG_FORMAT = "%(asctime)s [%(levelname)s] %(name)s: %(message)s"
_DATE_FORMAT = "%Y-%m-%d %H:%M:%S"

# 是否已完成初始化（避免重复添加 handler）
_initialized = False


def _init_root_logger():
    """初始化根 logger（仅执行一次）"""
    global _initialized
    if _initialized:
        return

    root = logging.getLogger(ROOT_LOGGER_NAME)
    root.setLevel(logging.DEBUG)

    # 避免重复添加 handler
    if root.handlers:
        _initialized = True
        return

    formatter = logging.Formatter(_LOG_FORMAT, datefmt=_DATE_FORMAT)

    # 控制台 handler（与原 print 行为兼容，INFO 级别）
    console_handler = logging.StreamHandler()
    console_handler.setLevel(logging.INFO)
    console_handler.setFormatter(formatter)
    root.addHandler(console_handler)

    # 文件 handler（DEBUG 级别，轮转）
    try:
        _LOG_DIR.mkdir(parents=True, exist_ok=True)
        file_handler = RotatingFileHandler(
            _LOG_FILE,
            maxBytes=1 * 1024 * 1024,  # 1MB
            backupCount=3,
            encoding="utf-8",
        )
        file_handler.setLevel(logging.DEBUG)
        file_handler.setFormatter(formatter)
        root.addHandler(file_handler)
    except OSError as e:
        # 文件 handler 初始化失败时，至少保证控制台日志可用
        root.error(f"无法初始化文件日志 handler: {e}")

    # 不向上传播到 root logger，避免重复输出
    root.propagate = False
    _initialized = True


def get_logger(name=None):
    """
    获取子 logger。

    参数：
      name: 模块名，通常传 __name__。None 时返回根 logger。
    """
    _init_root_logger()
    if name is None:
        return logging.getLogger(ROOT_LOGGER_NAME)
    # 不在 troubleshoot 命名空间下的，挂到根 logger 下
    if not name.startswith(ROOT_LOGGER_NAME):
        name = f"{ROOT_LOGGER_NAME}.{name}"
    return logging.getLogger(name)
