#!/usr/bin/env python3
"""
install-to-claude.py

Sync wiki-template's slash commands + subagents vào ~/.claude/ và setup
~/.claude/wiki-global.json với wiki_root trỏ về repo này.

Idempotent: re-run mỗi khi pull wiki-template mới để cập nhật.
Không động vào commands/agents user tự tạo (chỉ sync file đến từ wiki-template).

Usage:
  python scripts/install-to-claude.py [WIKI_ROOT] [--dry-run] [--force]

  WIKI_ROOT  Đường dẫn tuyệt đối đến wiki-template repo (default: parent
             của script này, tức là repo root khi chạy từ scripts/).
  --dry-run  In ra những gì sẽ làm, KHÔNG copy/ghi file.
  --force    Skip confirmation khi overwrite ~/.claude/wiki-global.json.
"""

import argparse
import filecmp
import json
import os
import re
import shutil
import sys
from pathlib import Path


def resolve_wiki_root(arg: str | None) -> Path:
    if arg:
        p = Path(arg).resolve()
    else:
        p = Path(__file__).resolve().parent.parent
    return p


def validate_wiki_root(wiki_root: Path) -> None:
    if not wiki_root.is_dir():
        print(f"✗ WIKI_ROOT không tồn tại: {wiki_root}", file=sys.stderr)
        sys.exit(1)
    if not (wiki_root / ".claude" / "commands").is_dir() or not (wiki_root / "agents").is_dir():
        print(
            f"✗ {wiki_root} không phải wiki-template repo (thiếu .claude/commands/ hoặc agents/).",
            file=sys.stderr,
        )
        sys.exit(1)


def sync_file(src: Path, dst: Path, label: str, dry_run: bool) -> None:
    if not dst.exists():
        print(f"  [NEW]       {label}")
        if not dry_run:
            dst.parent.mkdir(parents=True, exist_ok=True)
            shutil.copy2(src, dst)
    elif not filecmp.cmp(src, dst, shallow=False):
        print(f"  [UPDATED]   {label}")
        if not dry_run:
            shutil.copy2(src, dst)
    else:
        print(f"  [UNCHANGED] {label}")


def sync_dir(src_dir: Path, dst_dir: Path, label: str, dry_run: bool) -> None:
    print(f"── {label} → {dst_dir}")
    if not dry_run:
        dst_dir.mkdir(parents=True, exist_ok=True)

    md_files = sorted(src_dir.glob("*.md"))
    for src in md_files:
        sync_file(src, dst_dir / src.name, src.name, dry_run)
    print()


def handle_global_config(wiki_root: Path, global_config: Path, force: bool, dry_run: bool) -> None:
    print(f"── Global config → {global_config}")

    # JSON dùng forward slash để portable trên mọi OS
    wiki_root_fwd = wiki_root.as_posix()

    new_config = {
        "_comment": (
            "Generated by wiki-template/scripts/install-to-claude.py. "
            "wiki_root trỏ về wiki-template repo. "
            "Edit default_workspace nếu muốn fallback cho codebase chưa có .claude/wiki.json."
        ),
        "wiki_root": wiki_root_fwd,
        "default_workspace": None,
    }

    if not global_config.exists():
        print(f"  [NEW] {global_config}")
        if not dry_run:
            global_config.parent.mkdir(parents=True, exist_ok=True)
            global_config.write_text(
                json.dumps(new_config, ensure_ascii=False, indent=2), encoding="utf-8"
            )
    else:
        # Đọc wiki_root hiện tại
        try:
            existing = json.loads(global_config.read_text(encoding="utf-8"))
            current_root = existing.get("wiki_root", "")
        except (json.JSONDecodeError, OSError):
            current_root = ""

        if current_root == wiki_root_fwd:
            print(f"  [UNCHANGED] wiki_root đã đúng ({wiki_root_fwd})")
        else:
            print(f"  [CONFLICT] wiki_root hiện tại: {current_root or '<empty>'}")
            print(f"             wiki_root mới     : {wiki_root_fwd}")
            if force:
                print("  [FORCED]    overwrite (--force)")
                if not dry_run:
                    global_config.write_text(
                        json.dumps(new_config, ensure_ascii=False, indent=2), encoding="utf-8"
                    )
            else:
                print()
                print("  ⚠ Không tự overwrite (sẽ mất default_workspace user đã set).")
                print(f"    Để overwrite hoàn toàn:  python {__file__} {wiki_root} --force")
                print(f"    Hoặc edit thủ công:      {global_config}")
    print()


def main() -> None:
    parser = argparse.ArgumentParser(
        description="Sync wiki-template vào ~/.claude/ (Windows-compatible)",
        add_help=True,
    )
    parser.add_argument("wiki_root", nargs="?", default=None, help="Đường dẫn tới wiki-template repo")
    parser.add_argument("--dry-run", action="store_true", help="In ra kế hoạch, không thực thi")
    parser.add_argument("--force", action="store_true", help="Overwrite wiki-global.json kể cả khi xung đột")
    args = parser.parse_args()

    wiki_root = resolve_wiki_root(args.wiki_root)
    validate_wiki_root(wiki_root)

    global_claude = Path.home() / ".claude"
    global_commands = global_claude / "commands"
    global_agents = global_claude / "agents"
    global_config = global_claude / "wiki-global.json"

    print(f"Wiki root:  {wiki_root}")
    print(f"Global dir: {global_claude}")
    if args.dry_run:
        print("Mode:       DRY RUN (no changes)")
    print()

    # 1. Slash commands
    sync_dir(
        wiki_root / ".claude" / "commands",
        global_commands,
        "Slash commands",
        args.dry_run,
    )

    # 1b. Migrate legacy command files (pre-contextd rename)
    # Map legacy_name -> new_name. Most prefixes flip wiki-X -> contextd-X,
    # but the verbs use-wiki / update-wiki / rebase-wiki collapse the suffix.
    legacy_map = {
        "wiki-backup": "contextd-backup",
        "wiki-detect": "contextd-detect",
        "wiki-eval": "contextd-eval",
        "wiki-explain": "contextd-explain",
        "wiki-report": "contextd-report",
        "wiki-restore": "contextd-restore",
        "wiki-setup": "contextd-setup",
        "wiki-trace": "contextd-trace",
        "wiki-upgrade": "contextd-upgrade",
        "wiki-version": "contextd-version",
        "wiki-viz": "contextd-viz",
        "use-wiki": "use-contextd",
        "update-wiki": "update-contextd",
        "rebase-wiki": "rebase-contextd",
    }
    legacy_found = False
    for legacy, new_name in legacy_map.items():
        legacy_path = global_commands / f"{legacy}.md"
        if legacy_path.exists():
            legacy_found = True
            print(f"  [REMOVED]   {legacy}.md  (renamed → {new_name}.md)")
            if not args.dry_run:
                legacy_path.unlink()
    if legacy_found:
        print()
        print("  ⚠ Migration notice:")
        print("    Slash commands /wiki-*, /use-wiki, /update-wiki, /rebase-wiki đã đổi tên thành /contextd-*.")
        print("    Workspace mẫu 'wiki' đã đổi tên thành 'default'.")
        print("    Nếu codebase nào có .claude/wiki.json với \"workspace\": \"wiki\",")
        print("    cập nhật thành \"workspace\": \"default\" (hoặc chạy lại /switch-workspace).")
        print()

    # 2. Subagents
    sync_dir(
        wiki_root / ".claude" / "agents",
        global_agents,
        "Subagents",
        args.dry_run,
    )

    # 2b. Migrate legacy wiki-* subagents (pre-contextd rename)
    legacy_agents = {
        "wiki-planner": "contextd-planner",
        "wiki-context-selector": "contextd-context-selector",
        "wiki-plan-reviewer": "contextd-plan-reviewer (deprecated)",
        "wiki-curator": "contextd-curator",
        "wiki-reviewer": "contextd-reviewer",
    }
    for legacy, new_name in legacy_agents.items():
        legacy_path = global_agents / f"{legacy}.md"
        if legacy_path.exists():
            print(f"  [REMOVED]   {legacy}.md  (renamed → {new_name})")
            if not args.dry_run:
                legacy_path.unlink()

    # 2c. Remove deprecated subagents (merged into other agents).
    # contextd-plan-reviewer was merged into contextd-context-selector (pipeline 5→4 stages).
    deprecated_agents = ["contextd-plan-reviewer"]
    for agent_name in deprecated_agents:
        dep_path = global_agents / f"{agent_name}.md"
        if dep_path.exists():
            print(f"  [REMOVED]   {agent_name}.md  (deprecated — merged into contextd-context-selector)")
            if not args.dry_run:
                dep_path.unlink()
    print()

    # 3. wiki-global.json
    handle_global_config(wiki_root, global_config, args.force, args.dry_run)

    print("✓ Done.")
    print()
    print("Test thử:")
    print("  cd /path/to/your/codebase")
    print("  /contextd-setup           # tạo .claude/wiki.json cho codebase đó")
    print("  /list-workspaces      # xem có workspace nào trong wiki-template")
    print('  /use-contextd "...task..."  # dùng pipeline với context từ workspace active')


if __name__ == "__main__":
    main()
