"""主日志类模块"""
import atexit
import logging
import socket
from datetime import datetime
from typing import Any, Dict, Optional

from .config import LogConfig
from .async_handler import AsyncHandler
from .cache_manager import CacheManager
from ..transport.factory import TransportFactory

logger = logging.getLogger(__name__)


class Logger:
    """日志记录器主类
    
    提供简单的接口供业务代码使用，支持异步发送和自动降级
    """
    
    # 日志级别映射
    LEVELS = {
        "DEBUG": 10,
        "INFO": 20,
        "WARNING": 30,
        "ERROR": 40,
        "CRITICAL": 50
    }
    
    def __init__(
        self,
        app_name: str,
        server_url: str = "http://localhost:8080",
        transport: str = "http",
        **kwargs
    ):
        """初始化日志记录器
        
        Args:
            app_name: 应用名称
            server_url: 服务器地址
            transport: 传输协议 (http 或 grpc)
            **kwargs: 其他配置参数
        """
        # 创建配置
        self.config = LogConfig(
            app_name=app_name,
            server_url=server_url,
            transport=transport,
            **kwargs
        )
        
        # 获取主机名
        self.hostname = socket.gethostname()
        
        # 初始化缓存管理器
        self.cache_manager = CacheManager(self.config)
        
        # 初始化传输层
        self.transport = TransportFactory.create(self.config)
        
        # 初始化异步处理器
        self.async_handler = AsyncHandler(
            self.config,
            self.transport,
            self.cache_manager
        )
        
        # 注册退出时的清理函数
        atexit.register(self._cleanup)
        
        logger.info(f"Logger 已初始化: app={app_name}, transport={transport}")
    
    def _log(
        self,
        level: str,
        message: str,
        **metadata
    ):
        """内部日志记录方法
        
        Args:
            level: 日志级别
            message: 日志消息
            **metadata: 附加元数据
        """
        # 检查日志级别
        if self.LEVELS.get(level, 0) < self.LEVELS.get(self.config.log_level, 0):
            return
        
        # 构造日志条目
        log_entry = {
            "timestamp": datetime.utcnow().isoformat() + "Z",
            "level": level,
            "message": message,
            "metadata": {
                "app_name": self.config.app_name,
                "hostname": self.hostname,
                **metadata
            }
        }
        
        # 加入异步队列
        self.async_handler.enqueue(log_entry)
    
    def debug(self, message: str, **metadata):
        """记录 DEBUG 级别日志
        
        Args:
            message: 日志消息
            **metadata: 附加元数据
        """
        self._log("DEBUG", message, **metadata)
    
    def info(self, message: str, **metadata):
        """记录 INFO 级别日志
        
        Args:
            message: 日志消息
            **metadata: 附加元数据
        """
        self._log("INFO", message, **metadata)
    
    def warning(self, message: str, **metadata):
        """记录 WARNING 级别日志
        
        Args:
            message: 日志消息
            **metadata: 附加元数据
        """
        self._log("WARNING", message, **metadata)
    
    def error(self, message: str, **metadata):
        """记录 ERROR 级别日志
        
        Args:
            message: 日志消息
            **metadata: 附加元数据
        """
        self._log("ERROR", message, **metadata)
    
    def critical(self, message: str, **metadata):
        """记录 CRITICAL 级别日志
        
        Args:
            message: 日志消息
            **metadata: 附加元数据
        """
        self._log("CRITICAL", message, **metadata)
    
    def flush(self):
        """强制刷新缓冲区，立即发送所有待发送的日志"""
        self.async_handler.flush()
    
    def get_stats(self) -> Dict[str, Any]:
        """获取统计信息
        
        Returns:
            包含各组件统计信息的字典
        """
        return {
            "async_handler": self.async_handler.get_stats(),
            "cache": self.cache_manager.get_stats(),
            "transport": self.transport.get_stats()
        }
    
    def _cleanup(self):
        """清理资源"""
        logger.info("正在清理 Logger 资源...")
        try:
            self.async_handler.shutdown()
        except Exception as e:
            logger.error(f"清理异步处理器时异常: {e}")
