from __future__ import annotations
import os, json
from typing import List, Callable, Any

from .openapi_loader import load_openapi_operations, OpenAPIOperation
from .registry import ToolRegistry, ToolSpec
from .http_executor import OpenAPIHttpExecutor

def bind_openapi_directory(directory: str, registry: ToolRegistry, executor: OpenAPIHttpExecutor) -> List[str]:
    """Discover OpenAPI JSON specs and register *executable* tools bound to an HTTP executor."""
    added: List[str] = []
    for root, _, files in os.walk(directory):
        for f in files:
            if not f.lower().endswith(".json"):
                continue
            path = os.path.join(root, f)
            with open(path, "r", encoding="utf-8") as fp:
                spec = json.load(fp)

            for op in load_openapi_operations(spec):
                registry.register(_spec_for(op), _bound_tool(executor, op))
                added.append(op.tool_name)
    return added

def _spec_for(op: OpenAPIOperation) -> ToolSpec:
    return ToolSpec(
        name=op.tool_name,
        description=op.description,
        input_schema=op.input_schema,
        output_schema=op.output_schema,
        tags=["openapi", op.method.lower()],
    )

def _bound_tool(executor: OpenAPIHttpExecutor, op: OpenAPIOperation) -> Callable[..., Any]:
    async def _fn(**kwargs: Any) -> Any:
        return await executor.call(op, **kwargs)
    return _fn
