# -*- coding: utf-8 -*-
"""日志配置工具

提供统一的日志配置和格式化。
"""
from __future__ import annotations

import logging
import sys
from contextlib import contextmanager
from datetime import datetime
from pathlib import Path
from typing import Iterator, TextIO


# 统一日志格式（中文友好）
UNIFIED_FORMAT = "[%(asctime)s] %(levelname)-5s | %(name)s | %(message)s"
DATE_FORMAT = "%Y-%m-%d %H:%M:%S"


class TeeStream:
    """同时输出到多个流"""
    
    def __init__(self, *streams: TextIO) -> None:
        self._streams = streams

    def write(self, data: str) -> int:
        for stream in self._streams:
            stream.write(data)
        return len(data)

    def flush(self) -> None:
        for stream in self._streams:
            stream.flush()

    def isatty(self) -> bool:
        return False

    def fileno(self) -> int:
        return self._streams[0].fileno()


def build_log_path(log_dir: Path, prefix: str, tag: str = "") -> Path:
    """构建日志文件路径"""
    suffix = f"_{tag}" if tag else ""
    stamp = datetime.now().strftime("%Y%m%d_%H%M%S")
    return log_dir / f"{prefix}{suffix}_{stamp}.log"


def get_unified_formatter() -> logging.Formatter:
    """获取统一格式的日志格式器"""
    return logging.Formatter(UNIFIED_FORMAT, DATE_FORMAT)


@contextmanager
def configure_logging(
    name: str,
    log_file: Path | None,
    *,
    level: str = "INFO",
    console: bool = True,
    tee_std: bool = True,
) -> Iterator[logging.Logger]:
    """
    配置日志
    
    Args:
        name: 日志器名称
        log_file: 日志文件路径，None 表示不写文件
        level: 日志级别
        console: 是否输出到控制台
        tee_std: 是否将 stdout/stderr 也写入日志文件
    
    Yields:
        配置好的日志器
    """
    logger = logging.getLogger(name)
    logger.handlers.clear()
    logger.setLevel(getattr(logging, level.upper(), logging.INFO))
    logger.propagate = False

    formatter = get_unified_formatter()

    original_stdout = sys.stdout
    original_stderr = sys.stderr
    log_fp: TextIO | None = None

    try:
        if log_file:
            log_file.parent.mkdir(parents=True, exist_ok=True)
            log_fp = open(log_file, "a", encoding="utf-8", buffering=1)
            if tee_std:
                if console:
                    sys.stdout = TeeStream(original_stdout, log_fp)
                    sys.stderr = TeeStream(original_stderr, log_fp)
                else:
                    sys.stdout = log_fp
                    sys.stderr = log_fp
            file_handler = logging.StreamHandler(log_fp)
            file_handler.setFormatter(formatter)
            logger.addHandler(file_handler)

        if console:
            console_handler = logging.StreamHandler(original_stdout)
            console_handler.setFormatter(formatter)
            logger.addHandler(console_handler)

        yield logger
    finally:
        for handler in list(logger.handlers):
            handler.flush()
            handler.close()
            logger.removeHandler(handler)
        if log_fp:
            log_fp.flush()
            log_fp.close()
        sys.stdout = original_stdout
        sys.stderr = original_stderr


def setup_root_logger(level: str = "INFO") -> logging.Logger:
    """
    配置根日志器
    
    Args:
        level: 日志级别
    
    Returns:
        根日志器
    """
    root = logging.getLogger()
    root.setLevel(getattr(logging, level.upper(), logging.INFO))
    
    # 清除已有处理器
    root.handlers.clear()
    
    # 添加控制台处理器
    handler = logging.StreamHandler()
    handler.setFormatter(get_unified_formatter())
    root.addHandler(handler)
    
    return root
