import json
import os
import shlex
from pathlib import Path
from typing import Any

from harbor.agents.installed.base import BaseInstalledAgent, ExecInput
from harbor.models.agent.context import AgentContext
from harbor.models.agent.name import AgentName


class CursorCli(BaseInstalledAgent):
    """
    The Cursor CLI agent uses the Cursor AI command-line tool to solve tasks.
    """

    @staticmethod
    def name() -> str:
        return AgentName.CURSOR_CLI.value

    @property
    def _install_agent_template_path(self) -> Path:
        return Path(__file__).parent / "install-cursor-cli.sh.j2"

    def populate_context_post_run(self, context: AgentContext) -> None:
        pass

    def _build_register_mcp_servers_command(self) -> str | None:
        """Return a shell command that writes MCP config to ~/.cursor/mcp.json."""
        if not self.mcp_servers:
            return None
        servers: dict[str, dict[str, Any]] = {}
        for server in self.mcp_servers:
            if server.transport == "stdio":
                servers[server.name] = {"command": server.command, "args": server.args}
            else:  # sse or streamable-http
                servers[server.name] = {"url": server.url}
        config = json.dumps({"mcpServers": servers}, indent=2)
        escaped = shlex.quote(config)
        return f"mkdir -p ~/.cursor && echo {escaped} > ~/.cursor/mcp.json"

    def create_run_agent_commands(self, instruction: str) -> list[ExecInput]:
        escaped_instruction = shlex.quote(instruction)

        if not self.model_name or "/" not in self.model_name:
            raise ValueError("Model name must be in the format provider/model_name")

        model = self.model_name.split("/")[-1]

        # Handle API key
        env = {}
        if "CURSOR_API_KEY" in os.environ:
            env["CURSOR_API_KEY"] = os.environ["CURSOR_API_KEY"]
        else:
            raise ValueError(
                "CURSOR_API_KEY environment variable is required. "
                "Please set your Cursor API key."
            )

        commands: list[ExecInput] = []

        mcp_command = self._build_register_mcp_servers_command()
        if mcp_command:
            commands.append(ExecInput(command=mcp_command, env=env))

        commands.append(
            ExecInput(
                command=(
                    'export PATH="$HOME/.local/bin:$PATH"; '
                    f"cursor-agent --yolo --print --model={model} -- {escaped_instruction} "
                    f"2>&1 | stdbuf -oL tee /logs/agent/cursor-cli.txt"
                ),
                env=env,
            )
        )

        return commands
