from __future__ import annotations

import os
import threading
import time

from .adapters import discover_tools
from .config import MCP_CONFIG_PATH, sdk_installed, summarize_servers


_CACHE_TTL_SECONDS = 30.0
_CACHE_LOCK = threading.Lock()
_CACHE_RESULT: tuple[list, list[dict]] = ([], [])
_CACHE_AT_MONOTONIC = 0.0
_CACHE_CONFIG_MTIME: float | None = None
_LAST_MCP_PREF_ENABLED: bool | None = None


def _config_mtime() -> float | None:
    try:
        return float(os.path.getmtime(MCP_CONFIG_PATH))
    except Exception:
        return None


def get_mcp_discovery() -> tuple[list, list[dict]]:
    global _CACHE_RESULT, _CACHE_AT_MONOTONIC, _CACHE_CONFIG_MTIME, _LAST_MCP_PREF_ENABLED

    from agent_loop_config import get_mcp_enabled

    enabled = get_mcp_enabled()
    now = time.monotonic()
    mtime = _config_mtime()
    with _CACHE_LOCK:
        if _LAST_MCP_PREF_ENABLED is not None and enabled != _LAST_MCP_PREF_ENABLED:
            _CACHE_RESULT = ([], [])
            _CACHE_AT_MONOTONIC = 0.0
            _CACHE_CONFIG_MTIME = None
        _LAST_MCP_PREF_ENABLED = enabled

        if not enabled:
            return [], []

        if (
            _CACHE_AT_MONOTONIC > 0
            and (now - _CACHE_AT_MONOTONIC) <= _CACHE_TTL_SECONDS
            and mtime == _CACHE_CONFIG_MTIME
        ):
            tools, schemas = _CACHE_RESULT
            return list(tools), list(schemas)

    tools, schemas, _errors = discover_tools()
    with _CACHE_LOCK:
        _CACHE_RESULT = (list(tools), list(schemas))
        _CACHE_AT_MONOTONIC = now
        _CACHE_CONFIG_MTIME = mtime
    return list(tools), list(schemas)


def invalidate_discovery_cache() -> None:
    global _CACHE_RESULT, _CACHE_AT_MONOTONIC, _CACHE_CONFIG_MTIME, _LAST_MCP_PREF_ENABLED
    with _CACHE_LOCK:
        _CACHE_RESULT = ([], [])
        _CACHE_AT_MONOTONIC = 0.0
        _CACHE_CONFIG_MTIME = None
        _LAST_MCP_PREF_ENABLED = None


def cached_tool_count() -> int:
    from agent_loop_config import get_mcp_enabled

    if not get_mcp_enabled():
        return 0
    with _CACHE_LOCK:
        return len(_CACHE_RESULT[0])


def get_mcp_tools() -> list:
    tools, _ = get_mcp_discovery()
    return tools


def get_mcp_openai_schemas() -> list[dict]:
    _, schemas = get_mcp_discovery()
    return schemas
