"""Install Claude Code hooks for peon-loop reliability guarantees.

Usage:
    python -m peon_mcp.hooks.install

Writes/merges hooks into ~/.claude/settings.json. Idempotent — safe to run
multiple times. Preserves existing user hooks.
"""

import json
import sys
from pathlib import Path


PEON_HOOKS_CONFIG = {
    "PreToolUse": [
        {
            "matcher": "mcp__peon-mcp__update_task",
            "hooks": [{
                "type": "command",
                "command": "python3 -m peon_mcp.hooks.guard_done",
                "timeout": 10,
            }],
        },
        {
            "matcher": "Bash",
            "hooks": [{
                "type": "command",
                "command": "python3 -m peon_mcp.hooks.guard_pr",
                "timeout": 10,
            }],
        },
    ],
    "PostToolUse": [
        {
            "matcher": "mcp__peon-mcp__next_task",
            "hooks": [{
                "type": "command",
                "command": "python3 -m peon_mcp.hooks.session_link",
                "timeout": 5,
            }],
        },
        {
            "matcher": "*",
            "hooks": [{
                "type": "command",
                "command": "python3 -m peon_mcp.hooks.progress_reminder",
                "timeout": 5,
            }],
        },
    ],
}

# Marker to identify peon-managed hook entries
_PEON_MARKER = "python3 -m peon_mcp.hooks."


def _is_peon_hook(entry: dict) -> bool:
    """Check if a hook entry was installed by peon."""
    for hook in entry.get("hooks", []):
        cmd = hook.get("command", "")
        if _PEON_MARKER in cmd:
            return True
    return False


def install_hooks(settings_path: Path | None = None) -> Path:
    """Install peon hooks into Claude Code settings.json.

    Merges peon hooks with existing user hooks. Existing peon hooks are
    replaced; non-peon hooks are preserved.

    Args:
        settings_path: Override path (for testing). Defaults to ~/.claude/settings.json.

    Returns:
        Path to the written settings file.
    """
    if settings_path is None:
        settings_path = Path.home() / ".claude" / "settings.json"

    # Read existing settings
    existing: dict = {}
    if settings_path.exists():
        try:
            existing = json.loads(settings_path.read_text())
        except (json.JSONDecodeError, OSError):
            existing = {}

    # Get existing hooks section
    existing_hooks = existing.get("hooks", {})

    # Merge: for each hook type, keep non-peon entries + add peon entries
    merged_hooks: dict = {}

    # Process all hook types (existing + new)
    all_hook_types = set(list(existing_hooks.keys()) + list(PEON_HOOKS_CONFIG.keys()))

    for hook_type in all_hook_types:
        existing_entries = existing_hooks.get(hook_type, [])
        peon_entries = PEON_HOOKS_CONFIG.get(hook_type, [])

        # Keep non-peon entries from existing config
        user_entries = [e for e in existing_entries if not _is_peon_hook(e)]

        # Combine: user entries first, then peon entries
        merged = user_entries + peon_entries
        if merged:
            merged_hooks[hook_type] = merged

    # Update settings
    existing["hooks"] = merged_hooks

    # Write back
    settings_path.parent.mkdir(parents=True, exist_ok=True)
    settings_path.write_text(json.dumps(existing, indent=2) + "\n")

    return settings_path


def main() -> None:
    try:
        path = install_hooks()
        print(f"Peon hooks installed to {path}")
    except OSError as exc:
        # Non-fatal: hooks are important but shouldn't crash the process
        # (e.g. Docker builds with limited disk space).
        print(f"Warning: could not install hooks: {exc}", file=sys.stderr)
        sys.exit(0)


if __name__ == "__main__":
    main()
