"""Project detection for Memory Nexus MCP server.

Detects the current project from git remote URL and provides
a stable hash for cross-machine project identity.

Fallback chain:
1. git remote get-url origin -> SHA256[:12]
2. git rev-list --max-parents=0 HEAD -> first commit hash[:12]
3. basename of git root directory
"""

import hashlib
import json
import os
import subprocess
from datetime import datetime
from pathlib import Path
from typing import Optional


_REGISTRY_PATH = Path.home() / ".config" / "memory-nexus" / "projects.json"


def _run_git(args: list[str], cwd: str = ".") -> Optional[str]:
    """Run a git command, return stdout or None on failure."""
    if not os.path.isdir(cwd):
        return None
    try:
        result = subprocess.run(
            ["git"] + args,
            capture_output=True, text=True, timeout=5, cwd=cwd,
        )
        if result.returncode == 0:
            return result.stdout.strip()
    except (subprocess.TimeoutExpired, FileNotFoundError):
        pass
    return None


def detect_project(cwd: str = ".") -> tuple[str, str]:
    """Detect project identity from the working directory.

    Returns (project_hash, human_readable_name).
    """
    # Strategy 1: git remote URL
    remote = _run_git(["remote", "get-url", "origin"], cwd)
    if remote:
        h = hashlib.sha256(remote.encode()).hexdigest()[:12]
        name = remote.rstrip("/").split("/")[-1]
        if name.endswith(".git"):
            name = name[:-4]
        return h, name

    # Strategy 2: first commit hash (no remote)
    first_commit = _run_git(["rev-list", "--max-parents=0", "HEAD"], cwd)
    if first_commit:
        h = first_commit[:12]
        git_root = _run_git(["rev-parse", "--show-toplevel"], cwd)
        name = Path(git_root).name if git_root else Path(cwd).resolve().name
        return h, name

    # Strategy 3: directory basename
    resolved = Path(cwd).resolve()
    h = hashlib.sha256(str(resolved).encode()).hexdigest()[:12]
    return h, resolved.name


def get_hat_id(project_hash: str) -> str:
    return f"proj-{project_hash}"


def get_context_prefix(project_hash: str) -> str:
    return f"proj:{project_hash}"


def register_project(project_hash: str, name: str, remote: str = "") -> None:
    """Register a project in the local registry."""
    _REGISTRY_PATH.parent.mkdir(parents=True, exist_ok=True)
    registry = {}
    if _REGISTRY_PATH.exists():
        try:
            registry = json.loads(_REGISTRY_PATH.read_text())
        except (json.JSONDecodeError, OSError):
            pass
    registry[project_hash] = {
        "name": name,
        "remote": remote,
        "last_active": datetime.now().isoformat(),
    }
    _REGISTRY_PATH.write_text(json.dumps(registry, indent=2))


def is_first_connection(project_hash: str) -> bool:
    """Check if this is the first time connecting to this project."""
    if not _REGISTRY_PATH.exists():
        return True
    try:
        registry = json.loads(_REGISTRY_PATH.read_text())
        return project_hash not in registry
    except (json.JSONDecodeError, OSError):
        return True
