"""
SkyPlatform IAM SDK
提供FastAPI认证中间件和IAM服务连接功能
"""

from .config import AuthConfig
from .middleware import AuthMiddleware, AuthService, setup_auth_middleware, get_current_user, get_optional_user
from .connect_skyplatform_iam import ConnectSkyplatformIam
from .exceptions import (
    SkyPlatformAuthException,
    AuthenticationError,
    AuthorizationError,
    TokenExpiredError,
    TokenInvalidError,
    ConfigurationError,
    IAMServiceError,
    NetworkError
)

__version__ = "2.0.5"
__author__ = "x9"
__description__ = "SkyPlatform IAM认证SDK，提供FastAPI中间件和IAM服务连接功能"

# 全局IAM客户端实例
_global_iam_client = None

# 导出主要类和函数
__all__ = [
    # 配置
    "AuthConfig",
    
    # 中间件
    "AuthMiddleware",
    "AuthService",
    "setup_auth_middleware",
    "get_current_user",
    "get_optional_user",
    
    # 客户端
    "ConnectSkyplatformIam",
    "get_iam_client",
    
    # 异常
    "SkyPlatformAuthException",
    "AuthenticationError", 
    "AuthorizationError",
    "TokenExpiredError",
    "TokenInvalidError",
    "ConfigurationError",
    "IAMServiceError",
    "NetworkError",
    
    # 版本信息
    "__version__",
    "__author__",
    "__description__"
]


def create_auth_middleware(config: AuthConfig, **kwargs) -> AuthMiddleware:
    """
    创建认证中间件的便捷函数
    
    Args:
        config: 认证配置（必填）
        **kwargs: 其他中间件参数
        
    Returns:
        AuthMiddleware: 认证中间件实例
        
    Note:
        此函数用于创建中间件实例，用于请求拦截和鉴权。
        客户端应用需要自己实现具体的业务接口。
    """
    if config is None:
        raise ValueError("必须提供AuthConfig配置对象")
    return AuthMiddleware(config=config, **kwargs)


def init_skyplatform_iam(app, config: AuthConfig):
    """
    一键设置认证中间件的便捷函数
    
    Args:
        app: FastAPI应用实例
        config: 认证配置（必填）
        
    Returns:
        AuthMiddleware: 认证中间件实例
        
    Note:
        此函数只设置认证中间件，不包含预制路由。
        客户端应用需要根据业务需求自己实现认证相关的API接口。
        建议传入完整的AuthConfig对象以避免环境变量配置问题。
    """
    if config is None:
        raise ValueError("必须提供AuthConfig配置对象")
    
    # 验证配置的完整性
    config.validate_config()
    
    # 配置SDK日志级别
    _configure_sdk_logging(config.enable_sdk_logging)
    
    # 初始化全局认证服务
    setup_auth_middleware(config)
    
    # 启动时自动获取并注入machine_token
    try:
        iam_client = get_iam_client(config)
        iam_client.ensure_machine_token()
    except Exception:
        pass
    
    # 添加中间件
    middleware = AuthMiddleware(app=app, config=config)
    app.add_middleware(AuthMiddleware, config=config)
    
    return middleware


def _configure_sdk_logging(enable_sdk_logging: bool):
    """
    配置SDK日志级别
    
    Args:
        enable_sdk_logging: 是否启用SDK日志
    """
    import logging
    
    # SDK相关的logger名称列表
    sdk_loggers = [
        'skyplatform_iam.config',
        'skyplatform_iam.middleware',
        'skyplatform_iam.connect_skyplatform_iam',
        'skyplatform_iam.exceptions'
    ]
    
    if enable_sdk_logging:
        # 启用SDK日志，设置为INFO级别
        log_level = logging.INFO
    else:
        # 禁用SDK日志，设置为WARNING级别，只显示警告和错误
        log_level = logging.WARNING
    
    # 配置所有SDK相关的logger
    for logger_name in sdk_loggers:
        logger = logging.getLogger(logger_name)
        logger.setLevel(log_level)


def get_iam_client(config: AuthConfig = None) -> ConnectSkyplatformIam:
    """
    获取全局IAM客户端实例
    
    Args:
        config: 认证配置；如果未提供且未初始化，将报错
        
    Returns:
        ConnectSkyplatformIam: IAM客户端实例
        
    Note:
        此函数使用单例模式，确保整个应用中只有一个IAM客户端实例。
        第一次调用时会创建实例，后续调用会返回同一个实例。
        如果需要更新配置，可以传入新的config参数。
        
    Example:
        iam_client = get_iam_client()
        
        # 使用自定义配置
        config = AuthConfig(
            skyplatform_iam_host="https://iam.example.com",
            server_name="my_server",
            access_key="my_access_key"
        )
        iam_client = get_iam_client(config)
        
        # 调用IAM服务方法
        result = iam_client.register(
            cred_type="username",
            cred_value="test_user",
            password="password123"
        )
    """
    global _global_iam_client
    
    # 如果传入了新的配置，或者实例不存在，则创建/更新实例
    if config is not None:
        if _global_iam_client is None:
            _global_iam_client = ConnectSkyplatformIam(config=config)
        else:
            # 重新加载配置
            _global_iam_client.reload_config(config)
    elif _global_iam_client is None:
        raise ValueError("IAM客户端未初始化。请先调用 init_skyplatform_iam 或传入 AuthConfig")
    
    return _global_iam_client
