"""
Tool Templates - Copy and customize these for your agent.

Each tool needs:
1. Definition (JSON schema for the model)
2. Implementation (Python function)
"""

from pathlib import Path
import subprocess

WORKDIR = Path.cwd()


# =============================================================================
# TOOL DEFINITIONS (for TOOLS list)
# =============================================================================

BASH_TOOL = {
    "name": "bash",
    "description": "Run a shell command. Use for: ls, find, grep, git, npm, python, etc.",
    "input_schema": {
        "type": "object",
        "properties": {
            "command": {
                "type": "string",
                "description": "The shell command to execute"
            }
        },
        "required": ["command"],
    },
}

READ_FILE_TOOL = {
    "name": "read_file",
    "description": "Read file contents. Returns UTF-8 text.",
    "input_schema": {
        "type": "object",
        "properties": {
            "path": {
                "type": "string",
                "description": "Relative path to the file"
            },
            "limit": {
                "type": "integer",
                "description": "Max lines to read (default: all)"
            },
        },
        "required": ["path"],
    },
}

WRITE_FILE_TOOL = {
    "name": "write_file",
    "description": "Write content to a file. Creates parent directories if needed.",
    "input_schema": {
        "type": "object",
        "properties": {
            "path": {
                "type": "string",
                "description": "Relative path for the file"
            },
            "content": {
                "type": "string",
                "description": "Content to write"
            },
        },
        "required": ["path", "content"],
    },
}

EDIT_FILE_TOOL = {
    "name": "edit_file",
    "description": "Replace exact text in a file. Use for surgical edits.",
    "input_schema": {
        "type": "object",
        "properties": {
            "path": {
                "type": "string",
                "description": "Relative path to the file"
            },
            "old_text": {
                "type": "string",
                "description": "Exact text to find (must match precisely)"
            },
            "new_text": {
                "type": "string",
                "description": "Replacement text"
            },
        },
        "required": ["path", "old_text", "new_text"],
    },
}

TODO_WRITE_TOOL = {
    "name": "TodoWrite",
    "description": "Update the task list. Use to plan and track progress.",
    "input_schema": {
        "type": "object",
        "properties": {
            "items": {
                "type": "array",
                "description": "Complete list of tasks",
                "items": {
                    "type": "object",
                    "properties": {
                        "content": {"type": "string", "description": "Task description"},
                        "status": {"type": "string", "enum": ["pending", "in_progress", "completed"]},
                        "activeForm": {"type": "string", "description": "Present tense, e.g. 'Reading files'"},
                    },
                    "required": ["content", "status", "activeForm"],
                },
            }
        },
        "required": ["items"],
    },
}

TASK_TOOL_TEMPLATE = """
# Generate dynamically with agent types
TASK_TOOL = {
    "name": "Task",
    "description": f"Spawn a subagent for a focused subtask.\\n\\nAgent types:\\n{get_agent_descriptions()}",
    "input_schema": {
        "type": "object",
        "properties": {
            "description": {"type": "string", "description": "Short task name (3-5 words)"},
            "prompt": {"type": "string", "description": "Detailed instructions"},
            "agent_type": {"type": "string", "enum": list(AGENT_TYPES.keys())},
        },
        "required": ["description", "prompt", "agent_type"],
    },
}
"""


# =============================================================================
# TOOL IMPLEMENTATIONS
# =============================================================================

def safe_path(p: str) -> Path:
    """
    Security: Ensure path stays within workspace.
    Prevents ../../../etc/passwd attacks.
    """
    path = (WORKDIR / p).resolve()
    if not path.is_relative_to(WORKDIR):
        raise ValueError(f"Path escapes workspace: {p}")
    return path


def run_bash(command: str) -> str:
    """
    Execute shell command with safety checks.

    Safety features:
    - Blocks obviously dangerous commands
    - 60 second timeout
    - Output truncated to 50KB
    """
    dangerous = ["rm -rf /", "sudo", "shutdown", "reboot", "> /dev/"]
    if any(d in command for d in dangerous):
        return "Error: Dangerous command blocked"

    try:
        result = subprocess.run(
            command,
            shell=True,
            cwd=WORKDIR,
            capture_output=True,
            text=True,
            timeout=60
        )
        output = (result.stdout + result.stderr).strip()
        return output[:50000] if output else "(no output)"

    except subprocess.TimeoutExpired:
        return "Error: Command timed out (60s)"
    except Exception as e:
        return f"Error: {e}"


def run_read_file(path: str, limit: int = None) -> str:
    """
    Read file contents with optional line limit.

    Features:
    - Safe path resolution
    - Optional line limit for large files
    - Output truncated to 50KB
    """
    try:
        text = safe_path(path).read_text()
        lines = text.splitlines()

        if limit and limit < len(lines):
            lines = lines[:limit]
            lines.append(f"... ({len(text.splitlines()) - limit} more lines)")

        return "\n".join(lines)[:50000]

    except Exception as e:
        return f"Error: {e}"


def run_write_file(path: str, content: str) -> str:
    """
    Write content to file, creating parent directories if needed.

    Features:
    - Safe path resolution
    - Auto-creates parent directories
    - Returns byte count for confirmation
    """
    try:
        fp = safe_path(path)
        fp.parent.mkdir(parents=True, exist_ok=True)
        fp.write_text(content)
        return f"Wrote {len(content)} bytes to {path}"

    except Exception as e:
        return f"Error: {e}"


def run_edit_file(path: str, old_text: str, new_text: str) -> str:
    """
    Replace exact text in a file (surgical edit).

    Features:
    - Exact string matching (not regex)
    - Only replaces first occurrence (safety)
    - Clear error if text not found
    """
    try:
        fp = safe_path(path)
        content = fp.read_text()

        if old_text not in content:
            return f"Error: Text not found in {path}"

        new_content = content.replace(old_text, new_text, 1)
        fp.write_text(new_content)
        return f"Edited {path}"

    except Exception as e:
        return f"Error: {e}"


# =============================================================================
# DISPATCHER PATTERN
# =============================================================================

def execute_tool(name: str, args: dict) -> str:
    """
    Dispatch tool call to implementation.

    This pattern makes it easy to add new tools:
    1. Add definition to TOOLS list
    2. Add implementation function
    3. Add case to this dispatcher
    """
    if name == "bash":
        return run_bash(args["command"])
    if name == "read_file":
        return run_read_file(args["path"], args.get("limit"))
    if name == "write_file":
        return run_write_file(args["path"], args["content"])
    if name == "edit_file":
        return run_edit_file(args["path"], args["old_text"], args["new_text"])
    # Add more tools here...
    return f"Unknown tool: {name}"
