from __future__ import annotations
from typing import Any, Dict, List
from pydantic import BaseModel, Field

Json = Dict[str, Any]

class OpenAPIOperation(BaseModel):
    tool_name: str
    method: str
    path: str
    description: str = ""
    input_schema: Json = Field(default_factory=dict)
    output_schema: Json = Field(default_factory=dict)

def _normalize_tool_name(method: str, path: str) -> str:
    name = f"{method.lower()}_{path.strip('/').replace('/', '_').replace('{', '').replace('}', '')}"
    return name or "op"

def load_openapi_operations(spec: Json) -> List[OpenAPIOperation]:
    ops: List[OpenAPIOperation] = []
    paths = spec.get("paths", {}) or {}
    for path, methods in paths.items():
        for method, op in (methods or {}).items():
            if method.lower() not in {"get", "post", "put", "patch", "delete"}:
                continue
            tool_name = op.get("operationId") or _normalize_tool_name(method, path)
            desc = op.get("description") or op.get("summary") or ""
            req = (op.get("requestBody") or {}).get("content", {}) or {}
            input_schema = {}
            if req:
                app = req.get("application/json") or next(iter(req.values()), {})
                input_schema = (app.get("schema") or {}) if isinstance(app, dict) else {}
            resp = (op.get("responses") or {}).get("200") or (op.get("responses") or {}).get("201") or {}
            content = (resp.get("content") or {}) if isinstance(resp, dict) else {}
            output_schema = {}
            if content:
                app = content.get("application/json") or next(iter(content.values()), {})
                output_schema = (app.get("schema") or {}) if isinstance(app, dict) else {}
            ops.append(OpenAPIOperation(
                tool_name=tool_name,
                method=method.upper(),
                path=path,
                description=desc,
                input_schema=input_schema,
                output_schema=output_schema,
            ))
    return ops
