# Copyright (c) 2025, JINGROW and contributors
# For license information, please see license.txt

"""
Jingrow 白名单路由服务
"""

from fastapi import APIRouter, Request, HTTPException
from fastapi.responses import JSONResponse
import importlib
import inspect
from typing import Any, Dict, List
import logging
from jingrow import get_whitelisted_function, is_whitelisted
from jingrow.utils.auth import get_jingrow_api_headers, get_session_api_headers
from jingrow.utils.jingrow_api import get_logged_user

logger = logging.getLogger(__name__)
router = APIRouter()

async def authenticate_request(request: Request, allow_guest: bool) -> bool:
    """
    认证请求，支持两种认证方式：
    1. Session Cookie 认证
    2. API Key 认证
    """
    if allow_guest:
        return True
    
    # 方式1: 检查 Session Cookie 认证
    session_cookie = request.cookies.get('sid')
    if session_cookie:
        try:
            user = get_logged_user(session_cookie)
            if user:
                logger.info(f"Session认证成功: {user}")
                return True
        except Exception as e:
            logger.warning(f"Session认证失败: {e}")
    
    # 方式2: 检查 API Key 认证
    auth_header = request.headers.get('Authorization')
    if auth_header and auth_header.startswith('token '):
        try:
            # 验证API Key格式: token key:secret
            token_part = auth_header[6:]  # 移除 "token " 前缀
            if ':' in token_part:
                api_key, api_secret = token_part.split(':', 1)
                # 验证API Key是否有效
                expected_headers = get_jingrow_api_headers()
                if expected_headers and expected_headers.get('Authorization') == auth_header:
                    logger.info("API Key认证成功")
                    return True
        except Exception as e:
            logger.warning(f"API Key认证失败: {e}")
    
    logger.warning("认证失败: 未提供有效的认证信息")
    return False

@router.post("/{module_path:path}")
async def handle_request(request: Request, module_path: str):
    """
    处理白名单路由请求
    """
    try:
        # 首先检查是否是白名单函数
        if is_whitelisted(module_path):
            whitelist_info = get_whitelisted_function(module_path)
            func = whitelist_info['function']
            
            # 检查HTTP方法
            if request.method not in whitelist_info['methods']:
                raise HTTPException(status_code=405, detail=f"Method {request.method} not allowed for this endpoint")
            
            # 检查权限（如果需要）
            if not whitelist_info['allow_guest']:
                if not await authenticate_request(request, whitelist_info['allow_guest']):
                    raise HTTPException(status_code=401, detail="Authentication required")
            
            # 获取请求数据
            request_data = await request.json()
            
            # 调用函数
            result = func(**request_data)
            
            return JSONResponse(content={
                "success": True,
                "data": result
            })
        
        # 如果不是白名单函数，使用原有的动态导入方式
        # 解析模块路径
        module_info = parse_module_path(module_path)
        
        # 动态导入模块
        module = import_module(module_info['module_path'])
        
        # 获取函数
        function_name = module_info['function_name']
        if not hasattr(module, function_name):
            raise HTTPException(status_code=404, detail=f"Function {function_name} not found in module {module_info['module_path']}")
        
        func = getattr(module, function_name)
        
        # 获取请求数据
        request_data = await request.json()
        
        # 调用函数
        result = func(**request_data)
        
        return JSONResponse(content={
            "success": True,
            "data": result
        })
        
    except Exception as e:
        logger.error(f"Request handler error: {e}")
        raise HTTPException(status_code=500, detail=str(e))

def parse_module_path(module_path: str) -> Dict[str, str]:
    """解析模块路径"""
    parts = module_path.split('.')
    
    if len(parts) < 2:
        raise ValueError("Invalid module path format")
    
    # 最后一部分是函数名
    function_name = parts[-1]
    
    # 其余部分是模块路径
    module_path = '.'.join(parts[:-1])
    
    return {
        'module_path': module_path,
        'function_name': function_name
    }

def import_module(module_path: str):
    """动态导入模块"""
    try:
        return importlib.import_module(module_path)
    except ImportError as e:
        logger.error(f"Failed to import module {module_path}: {e}")
        raise HTTPException(status_code=404, detail=f"Module {module_path} not found")

