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

from typing import Dict, List, Any, Optional, Union
import functools
import inspect
import logging
from jingrow.model.page import Page
from jingrow.config import Config

_adapter = None
_local = {}

def _init_adapter(run_mode: str = "api"):
    global _adapter
    
    if run_mode == "api":
        from .adapters.api_adapter import ApiAdapter
        _adapter = ApiAdapter()
    elif run_mode == "local":
        from .adapters.local_adapter import LocalAdapter
        _adapter = LocalAdapter()
    else:
        raise ValueError(f"Unsupported run_mode: {run_mode}. Supported modes: 'api', 'local'")

def get_pg(pagetype: str, name: str = None, **kwargs):
    return _adapter.get_pg(pagetype, name, **kwargs)

def get_list(pagetype: str, *args, **kwargs):
    return _adapter.get_list(pagetype, *args, **kwargs)

def new_pg(pagetype: str, **kwargs):
    return _adapter.new_pg(pagetype, **kwargs)

def save_pg(pg):
    return _adapter.save_pg(pg)

def delete_pg(pagetype: str, name: str):
    return _adapter.delete_pg(pagetype, name)

def db_exists(pagetype: str, filters: Dict[str, Any] = None):
    return _adapter.db_exists(pagetype, filters)

def db_get_value(pagetype: str, filters: Dict[str, Any] = None, fieldname: str = None):
    return _adapter.db_get_value(pagetype, filters, fieldname)

def db_set_value(pagetype: str, filters: Dict[str, Any] = None, fieldname: str = None, value: Any = None):
    return _adapter.db_set_value(pagetype, filters, fieldname, value)

def log_error(title: str, message: str):
    return _adapter.log_error(title, message)

def throw(title: str, message: str):
    return _adapter.throw(title, message)

def _dict():
    """创建一个空字典"""
    return {}

# =============== Whitelist 实现 ===============
_logger = logging.getLogger(__name__)
_whitelisted_functions: Dict[str, Dict[str, Any]] = {}

def whitelist(allow_guest: bool = False, methods: List[str] = None):
    if methods is None:
        methods = ['POST']

    def decorator(func):
        module_name = func.__module__
        function_name = func.__name__
        api_path = f"{module_name}.{function_name}"

        sig = inspect.signature(func)
        parameters: Dict[str, Dict[str, Any]] = {}
        for param_name, param in sig.parameters.items():
            parameters[param_name] = {
                'name': param_name,
                'annotation': None if param.annotation is inspect._empty else param.annotation,
                'default': None if param.default is inspect._empty else param.default,
                'kind': param.kind,
            }

        _whitelisted_functions[api_path] = {
            'function': func,
            'module_path': module_name,
            'function_name': function_name,
            'allow_guest': allow_guest,
            'methods': methods,
            'parameters': parameters,
            'docstring': func.__doc__ or "",
        }

        _logger.info(
            f"Whitelisted function registered: {api_path} (methods={methods}, allow_guest={allow_guest})"
        )

        @functools.wraps(func)
        def wrapper(*args, **kwargs):
            return func(*args, **kwargs)

        return wrapper

    return decorator

def get_whitelisted_functions() -> Dict[str, Dict[str, Any]]:
    return _whitelisted_functions.copy()

def is_whitelisted(api_path: str) -> bool:
    return api_path in _whitelisted_functions

def get_whitelisted_function(api_path: str):
    return _whitelisted_functions.get(api_path)


# 兼容性属性
db = type('db', (), {
    'exists': db_exists,
    'get_value': db_get_value,
    'set_value': db_set_value,
})()

# 初始化默认配置
_init_adapter(Config.run_mode)
