"""MCP tools that proxy to cube-cloud.

These tools are forwarded verbatim — the agent just passes arguments through
and returns the remote response. All the logic lives server-side.
"""

from __future__ import annotations

from mcp.types import Tool

# Tools that are proxied to cube-cloud (no local execution needed)
REMOTE_TOOLS: list[Tool] = [
    Tool(
        name="list_environments",
        description=(
            "List Apollo environments with their IDs and RIDs. "
            "Optionally filter by name substring."
        ),
        inputSchema={
            "type": "object",
            "properties": {
                "search": {
                    "type": "string",
                    "description": 'Optional name substring to filter by (case-insensitive). Example: "pep".',
                },
            },
        },
    ),
    Tool(
        name="create_environment",
        description="Create a new Apollo environment and install the Apollo Control Plane module.",
        inputSchema={
            "type": "object",
            "properties": {
                "name": {
                    "type": "string",
                    "description": 'Environment name (e.g. "my-cube-test"). Must be unique.',
                },
                "accreditation": {
                    "type": "string",
                    "description": "Accreditation level. Defaults to DEV.",
                    "default": "DEV",
                },
            },
            "required": ["name"],
        },
    ),
    Tool(
        name="replicate_environment",
        description=(
            "Replicate an Apollo environment into a new or existing environment. "
            "Copies modules, entities, config overrides, and reports secrets."
        ),
        inputSchema={
            "type": "object",
            "properties": {
                "source": {
                    "type": "string",
                    "description": "Source environment name or RID.",
                },
                "target": {
                    "type": "string",
                    "description": "Target environment name. Created if it doesn't exist.",
                },
                "accreditation": {
                    "type": "string",
                    "description": "Accreditation for new environments. Defaults to DEV.",
                    "default": "DEV",
                },
            },
            "required": ["source", "target"],
        },
    ),
    Tool(
        name="install_entity",
        description="Install a Helm chart entity on an Apollo environment.",
        inputSchema={
            "type": "object",
            "properties": {
                "environment": {
                    "type": "string",
                    "description": "Target environment name or RID.",
                },
                "entity_name": {
                    "type": "string",
                    "description": "Helm chart name (e.g. mosquitto).",
                },
                "product_id": {
                    "type": "string",
                    "description": 'Product maven coordinate "groupId:artifactId".',
                },
                "k8s_namespace": {
                    "type": "string",
                    "description": "Kubernetes namespace. Defaults to default.",
                    "default": "default",
                },
                "config_overrides": {
                    "type": "string",
                    "description": "Optional JSON config overrides.",
                },
            },
            "required": ["environment", "entity_name", "product_id"],
        },
    ),
    Tool(
        name="entity_health",
        description="Get health and activity status of entities in an Apollo environment.",
        inputSchema={
            "type": "object",
            "properties": {
                "environment": {
                    "type": "string",
                    "description": "Environment name or RID.",
                },
                "entity_id": {
                    "type": "string",
                    "description": "Optional entity display name to filter by.",
                },
            },
            "required": ["environment"],
        },
    ),
    Tool(
        name="plan_details",
        description="Get detailed plan information for an entity, including tasks, events, and error logs.",
        inputSchema={
            "type": "object",
            "properties": {
                "environment": {
                    "type": "string",
                    "description": "Environment name or RID.",
                },
                "entity_name": {
                    "type": "string",
                    "description": "Entity display name (substring match).",
                },
                "plan_index": {
                    "type": "integer",
                    "description": "Which plan to show (0 = most recent). Defaults to 0.",
                    "default": 0,
                },
            },
            "required": ["environment", "entity_name"],
        },
    ),
    Tool(
        name="acr_get_token",
        description="Get an OAuth2 access token from Apollo Container Registry.",
        inputSchema={"type": "object", "properties": {}},
    ),
    Tool(
        name="apollo_publish_manifest",
        description="Publish an Apollo manifest YAML to make a Helm chart available for deployment.",
        inputSchema={
            "type": "object",
            "properties": {
                "manifest_yaml": {
                    "type": "string",
                    "description": "The manifest YAML content to publish.",
                },
            },
            "required": ["manifest_yaml"],
        },
    ),
    # Environment management
    Tool(
        name="delete_environment",
        description=(
            "Delete an Apollo environment. Opens a change request to delete the "
            "specified environment. This is a destructive operation that will remove "
            "the environment and all its entities, modules, and configuration."
        ),
        inputSchema={
            "type": "object",
            "properties": {
                "environment": {
                    "type": "string",
                    "description": 'Environment name or RID to delete (e.g. "my-test-env").',
                },
            },
            "required": ["environment"],
        },
    ),
    Tool(
        name="reset_environment_agents",
        description=(
            "Reset all agents on an Apollo environment, forcing full re-evaluation. "
            "Triggers agents to re-evaluate all entities, effectively forcing version "
            "enforcement and config re-synchronization. WARNING: resets ALL agents."
        ),
        inputSchema={
            "type": "object",
            "properties": {
                "environment": {
                    "type": "string",
                    "description": 'Environment name or RID (e.g. "pep-onlogicmc610-4").',
                },
            },
            "required": ["environment"],
        },
    ),
    # Entity management
    Tool(
        name="uninstall_entity",
        description=(
            "Uninstall an entity from an Apollo environment. Removes the specified "
            "entity (Helm chart) via a change request. Use entity_health to find "
            "entity names and plan_details to monitor uninstall progress."
        ),
        inputSchema={
            "type": "object",
            "properties": {
                "environment": {
                    "type": "string",
                    "description": 'Environment name or RID (e.g. "pep-onlogicmc610-4").',
                },
                "entity_name": {
                    "type": "string",
                    "description": 'Entity display name or entity name (substring match, e.g. "mosquitto").',
                },
            },
            "required": ["environment", "entity_name"],
        },
    ),
    Tool(
        name="update_entity_config",
        description=(
            "Update configuration overrides for an entity in an Apollo environment. "
            "Sets or replaces the config overrides (Helm value overrides). "
            "Use entity_health to see current entity status before updating."
        ),
        inputSchema={
            "type": "object",
            "properties": {
                "environment": {
                    "type": "string",
                    "description": 'Environment name or RID (e.g. "pep-onlogicmc610-4").',
                },
                "entity_name": {
                    "type": "string",
                    "description": "Entity display name or entity name (substring match).",
                },
                "config": {
                    "type": "string",
                    "description": "JSON object of config overrides (e.g. '{\"replicaCount\": 2}').",
                },
            },
            "required": ["environment", "entity_name", "config"],
        },
    ),
    Tool(
        name="enforce_entity_config",
        description=(
            "Force config re-enforcement on an entity. Re-submits current config "
            "overrides, triggering Apollo to create a new enforce config plan. "
            "Useful when config has drifted or a previous enforcement failed."
        ),
        inputSchema={
            "type": "object",
            "properties": {
                "environment": {
                    "type": "string",
                    "description": 'Environment name or RID (e.g. "pep-onlogicmc610-4").',
                },
                "entity_name": {
                    "type": "string",
                    "description": "Entity display name or entity name (substring match).",
                },
            },
            "required": ["environment", "entity_name"],
        },
    ),
    # Module management
    Tool(
        name="list_modules",
        description=(
            "List modules installed on an Apollo environment. Shows display names, "
            "maven coordinates, state, variables, and RIDs. Use this before "
            "updating variables or unlinking a module."
        ),
        inputSchema={
            "type": "object",
            "properties": {
                "environment": {
                    "type": "string",
                    "description": 'Environment name or RID (e.g. "pep-onlogicmc610-4").',
                },
                "search": {
                    "type": "string",
                    "description": "Optional substring to filter modules by name or coordinate (case-insensitive).",
                },
            },
            "required": ["environment"],
        },
    ),
    Tool(
        name="install_module",
        description=(
            "Install a module on an Apollo environment. Modules are collections of "
            "related entities managed together. If already installed, use "
            "update_module_variables to change variables."
        ),
        inputSchema={
            "type": "object",
            "properties": {
                "environment": {
                    "type": "string",
                    "description": 'Target environment name or RID (e.g. "pep-onlogicmc610-4").',
                },
                "maven_coordinate": {
                    "type": "string",
                    "description": 'Module maven coordinate (e.g. "module:builtin-control-plane-minimal:0.0.40").',
                },
                "variables": {
                    "type": "string",
                    "description": "Optional JSON object of module variables as {\"varName\": \"value\", ...}.",
                },
                "display_name": {
                    "type": "string",
                    "description": "Optional display name for the module installation.",
                },
                "ignore_secret_requirements": {
                    "type": "boolean",
                    "description": "If true, allows installation even if required secrets are not set.",
                    "default": False,
                },
            },
            "required": ["environment", "maven_coordinate"],
        },
    ),
    Tool(
        name="uninstall_module",
        description=(
            "Uninstall (unlink) a module from an Apollo environment. Does NOT "
            "automatically remove entities it installed — they become direct entities. "
            "Use uninstall_entity separately to remove individual entities."
        ),
        inputSchema={
            "type": "object",
            "properties": {
                "environment": {
                    "type": "string",
                    "description": 'Environment name or RID (e.g. "pep-onlogicmc610-4").',
                },
                "module_name": {
                    "type": "string",
                    "description": 'Module display name or maven coordinate substring (e.g. "control-plane").',
                },
            },
            "required": ["environment", "module_name"],
        },
    ),
    Tool(
        name="update_module_variables",
        description=(
            "Update variables on an installed module. Triggers Apollo to reconcile "
            "the module's entities with new variable values. Use list_modules to "
            "see current values before updating."
        ),
        inputSchema={
            "type": "object",
            "properties": {
                "environment": {
                    "type": "string",
                    "description": 'Environment name or RID (e.g. "pep-onlogicmc610-4").',
                },
                "module_name": {
                    "type": "string",
                    "description": "Module display name or maven coordinate substring.",
                },
                "variables": {
                    "type": "string",
                    "description": 'JSON object of variables to update as {"varName": "newValue", ...}.',
                },
            },
            "required": ["environment", "module_name", "variables"],
        },
    ),
    # Secret management
    Tool(
        name="create_secret",
        description=(
            "Create a secret for an entity in an Apollo environment. "
            "For single-value secrets, provide secret_value. "
            "For multi-key secrets, provide secret_keys as a JSON object."
        ),
        inputSchema={
            "type": "object",
            "properties": {
                "environment": {
                    "type": "string",
                    "description": 'Environment name or RID (e.g. "pep-onlogicmc610-4").',
                },
                "entity_name": {
                    "type": "string",
                    "description": "Entity display name or entity name (substring match).",
                },
                "secret_name": {
                    "type": "string",
                    "description": 'Name for the secret (e.g. "mqtt-credentials").',
                },
                "secret_value": {
                    "type": "string",
                    "description": "Value for a single-value secret. Mutually exclusive with secret_keys.",
                },
                "secret_keys": {
                    "type": "string",
                    "description": "JSON object of key-value pairs for a multi-key secret.",
                },
                "description": {
                    "type": "string",
                    "description": "Optional description for the secret.",
                },
            },
            "required": ["environment", "entity_name", "secret_name"],
        },
    ),
    Tool(
        name="update_secret",
        description=(
            "Update an existing secret for an entity. For single-value: provide "
            "secret_value. For multi-key: provide secret_key and secret_key_value."
        ),
        inputSchema={
            "type": "object",
            "properties": {
                "environment": {
                    "type": "string",
                    "description": 'Environment name or RID (e.g. "pep-onlogicmc610-4").',
                },
                "entity_name": {
                    "type": "string",
                    "description": "Entity display name or entity name (substring match).",
                },
                "secret_name": {
                    "type": "string",
                    "description": "Name of the existing secret to update.",
                },
                "secret_value": {
                    "type": "string",
                    "description": "New value for a single-value secret.",
                },
                "secret_key": {
                    "type": "string",
                    "description": "Key name to set/update in a multi-key secret.",
                },
                "secret_key_value": {
                    "type": "string",
                    "description": "Value for the key specified by secret_key.",
                },
                "description": {
                    "type": "string",
                    "description": "New description for the secret.",
                },
            },
            "required": ["environment", "entity_name", "secret_name"],
        },
    ),
    # Product & release channel management
    Tool(
        name="list_products",
        description=(
            "List available products in Apollo. Products represent deployable software "
            "(Helm charts, assets). Use this to discover product IDs for install_entity."
        ),
        inputSchema={
            "type": "object",
            "properties": {
                "search": {
                    "type": "string",
                    "description": "Optional substring to filter products by name or ID (case-insensitive).",
                },
                "page_size": {
                    "type": "integer",
                    "description": "Number of products to return (default 50, max 200).",
                    "default": 50,
                },
            },
        },
    ),
    Tool(
        name="compare_product_versions",
        description=(
            "Compare what version of a product is installed across multiple environments. "
            "Shows installed version, rollout status, health, and release channel."
        ),
        inputSchema={
            "type": "object",
            "properties": {
                "product_id": {
                    "type": "string",
                    "description": 'Product maven coordinate "groupId:artifactId" (e.g. "com.edgescaleai-cube:esai-platform-z").',
                },
                "environments": {
                    "type": "string",
                    "description": 'Comma-separated environment names (e.g. "pep-onlogicmc610-4, joel-cube").',
                },
            },
            "required": ["product_id", "environments"],
        },
    ),
    Tool(
        name="list_release_channels",
        description=(
            "List available Apollo release channels. By default only shows ordinary "
            "(non-environment-specific) channels."
        ),
        inputSchema={
            "type": "object",
            "properties": {
                "search": {
                    "type": "string",
                    "description": "Optional substring to filter channels by name (case-insensitive).",
                },
                "include_env_specific": {
                    "type": "boolean",
                    "description": "If true, also show environment-specific channels.",
                    "default": False,
                },
            },
        },
    ),
    Tool(
        name="get_product_releases",
        description=(
            "Get release history for a product, showing versions and their release channels. "
            "Use this to find the release RID needed for add_product_to_release_channel."
        ),
        inputSchema={
            "type": "object",
            "properties": {
                "product_id": {
                    "type": "string",
                    "description": 'Product maven coordinate "groupId:artifactId" (e.g. "com.edgescaleai-cube:esai-platform-z").',
                },
                "page_size": {
                    "type": "integer",
                    "description": "Number of releases to return (default 10, max 50).",
                    "default": 10,
                },
            },
            "required": ["product_id"],
        },
    ),
    Tool(
        name="add_product_to_release_channel",
        description=(
            "Add a product release to one or more release channels. Promotes a specific "
            "version to the given channels. Use get_product_releases to find versions."
        ),
        inputSchema={
            "type": "object",
            "properties": {
                "product_id": {
                    "type": "string",
                    "description": 'Product maven coordinate "groupId:artifactId".',
                },
                "version": {
                    "type": "string",
                    "description": 'The version to promote (e.g. "0.5.4").',
                },
                "channels": {
                    "type": "string",
                    "description": 'Comma-separated release channel names (e.g. "INT, PRE-PROD").',
                },
                "rationale": {
                    "type": "string",
                    "description": "Reason for the promotion.",
                },
            },
            "required": ["product_id", "version", "channels"],
        },
    ),
    Tool(
        name="remove_product_from_release_channel",
        description=(
            "Remove a product release from one or more release channels. "
            "Use get_product_releases to see current channel memberships."
        ),
        inputSchema={
            "type": "object",
            "properties": {
                "product_id": {
                    "type": "string",
                    "description": 'Product maven coordinate "groupId:artifactId".',
                },
                "version": {
                    "type": "string",
                    "description": 'The version to demote (e.g. "0.5.4").',
                },
                "channels": {
                    "type": "string",
                    "description": 'Comma-separated release channel names to remove from.',
                },
                "rationale": {
                    "type": "string",
                    "description": "Reason for the demotion.",
                },
            },
            "required": ["product_id", "version", "channels"],
        },
    ),
    Tool(
        name="set_label_on_product",
        description=(
            "Set a label on a product. Labels are used by release channels with "
            "label requirements and for organizing/filtering products."
        ),
        inputSchema={
            "type": "object",
            "properties": {
                "product_id": {
                    "type": "string",
                    "description": 'Product maven coordinate "groupId:artifactId".',
                },
                "label_id": {
                    "type": "string",
                    "description": 'The label ID to set (e.g. "customer", "tier").',
                },
                "label_value": {
                    "type": "string",
                    "description": 'The value for the label (e.g. "lear", "production").',
                },
            },
            "required": ["product_id", "label_id", "label_value"],
        },
    ),
    Tool(
        name="remove_label_from_product",
        description="Remove a label from a product.",
        inputSchema={
            "type": "object",
            "properties": {
                "product_id": {
                    "type": "string",
                    "description": 'Product maven coordinate "groupId:artifactId".',
                },
                "label_id": {
                    "type": "string",
                    "description": 'The label ID to remove (e.g. "customer", "tier").',
                },
            },
            "required": ["product_id", "label_id"],
        },
    ),
    # Change request management
    Tool(
        name="list_change_requests",
        description=(
            "List Apollo change requests, optionally filtered by environment and status. "
            "Use this to find CR RIDs for review_change_request."
        ),
        inputSchema={
            "type": "object",
            "properties": {
                "environment": {
                    "type": "string",
                    "description": "Optional environment name to filter by.",
                },
                "status": {
                    "type": "string",
                    "description": "Optional status filter: PENDING_APPROVALS, APPROVED, APPROVED_APPLYING, APPROVED_MERGED, CANCELLED, REJECTED, ERROR.",
                },
                "page_size": {
                    "type": "integer",
                    "description": "Number of results (default 10, max 50).",
                    "default": 10,
                },
            },
        },
    ),
    Tool(
        name="review_change_request",
        description=(
            "Review (approve, reject, or cancel) an Apollo change request. "
            "Use list_change_requests to find the CR RID."
        ),
        inputSchema={
            "type": "object",
            "properties": {
                "rid": {
                    "type": "string",
                    "description": 'The change request RID (e.g. "ri.approval.1.request.xxx").',
                },
                "action": {
                    "type": "string",
                    "description": 'One of "approve", "reject", or "cancel".',
                },
                "comment": {
                    "type": "string",
                    "description": "Required for reject. Optional for approve.",
                },
            },
            "required": ["rid", "action"],
        },
    ),
    # Phase 2: Server-side Teleport + kubectl tools
    Tool(
        name="cube_status",
        description="Get the status of a Cube node (server-side kubectl via tbot).",
        inputSchema={
            "type": "object",
            "properties": {
                "cluster": {
                    "type": "string",
                    "description": "Cube cluster name (from cube_list).",
                },
            },
            "required": ["cluster"],
        },
    ),
    Tool(
        name="cube_list",
        description="List available Cube clusters accessible via server-side tbot.",
        inputSchema={"type": "object", "properties": {}},
    ),
    Tool(
        name="kubectl_exec",
        description=(
            "Execute a kubectl command server-side. "
            "Destructive commands (delete, apply, create, etc.) are blocked."
        ),
        inputSchema={
            "type": "object",
            "properties": {
                "cluster": {
                    "type": "string",
                    "description": "Target Cube cluster name (from cube_list).",
                },
                "command": {
                    "type": "string",
                    "description": 'kubectl command without the "kubectl" prefix. Example: "get pods -n default".',
                },
            },
            "required": ["cluster", "command"],
        },
    ),
    Tool(
        name="app_list",
        description="List available Teleport apps (server-side via tbot).",
        inputSchema={
            "type": "object",
            "properties": {
                "company": {
                    "type": "string",
                    "description": 'Optional filter by company label (e.g. "edgescaleai", "lear").',
                },
            },
        },
    ),
    Tool(
        name="cube_cluster_login",
        description=(
            "Generate a self-contained kubeconfig for a Cube cluster. "
            "Returns a kubeconfig YAML with embedded TLS certs (no tsh or tbot needed locally)."
        ),
        inputSchema={
            "type": "object",
            "properties": {
                "cluster": {
                    "type": "string",
                    "description": "Cube cluster name (from cube_list).",
                },
            },
            "required": ["cluster"],
        },
    ),
]

REMOTE_TOOL_NAMES = {t.name for t in REMOTE_TOOLS}
