"""Generate agent tool definitions without exposing app implementation details."""

from __future__ import annotations

from typing import Any

from bridge_platform.apps.contracts import ActionContract, AppManifest


def compact_tool(manifest: AppManifest, action: str, contract: ActionContract) -> dict[str, Any]:
    agent = contract.agent
    if agent is None or not agent.exposed:
        raise ValueError("Capability is not exposed to agents")
    return {
        "app_id": manifest.app_id,
        "app_version": manifest.app_version,
        "capability": contract.capability,
        "title": agent.title,
        "summary": agent.summary,
        "domains": list(agent.domains),
        "risk": {"category": agent.risk_category, "level": agent.risk_level},
        "confirmation": agent.confirmation,
    }


def full_tool(manifest: AppManifest, action: str, contract: ActionContract) -> dict[str, Any]:
    tool = compact_tool(manifest, action, contract)
    agent = contract.agent
    tool.update({
        "tool_schema_version": "1.0",
        "use_when": list(agent.use_when),
        "do_not_use_when": list(agent.do_not_use_when),
        "input_schema": contract.input_schema or {"type": "object", "properties": {}},
        "output_schema": contract.output_schema,
        "errors": list(contract.errors),
        "required_permissions": list(agent.required_permissions),
        "allowed_roles": list(agent.allowed_roles),
        "execution": {
            "action": action,
            "timeout_seconds": contract.timeout_seconds,
            "side_effects": contract.side_effects,
            "idempotent": contract.idempotent,
            "idempotency_key_required": contract.idempotency_key_required,
            "data_classification": contract.data_classification,
        },
    })
    return tool


def manifest_tools(manifest: AppManifest, *, compact: bool = True) -> list[dict[str, Any]]:
    render = compact_tool if compact else full_tool
    return [
        render(manifest, action, contract)
        for action, contract in manifest.actions.items()
        if contract.agent is not None and contract.agent.exposed
    ]
