"""
neurocli context — gather project context (git, file tree, env)
"""
import os
import subprocess
from pathlib import Path

SENSITIVE_PATTERNS = [".env", ".env.", "secret", "private_key", "id_rsa", ".pem", "token", "password"]
SKIP_DIRS = {".git", "node_modules", "__pycache__", ".venv", "venv", "dist", "build", ".next"}
MAX_FILE_SIZE = 50 * 1024  # 50KB


def is_sensitive(path: str) -> bool:
    p = Path(path).name.lower()
    return any(pat in p for pat in SENSITIVE_PATTERNS)


def get_file_tree(root: str = ".", max_depth: int = 3) -> str:
    lines = []
    root_path = Path(root).resolve()

    def walk(path: Path, depth: int, prefix: str = ""):
        if depth > max_depth:
            return
        try:
            entries = sorted(path.iterdir(), key=lambda x: (x.is_file(), x.name))
        except PermissionError:
            return
        for i, entry in enumerate(entries):
            if entry.name in SKIP_DIRS or entry.name.startswith("."):
                continue
            connector = "└── " if i == len(entries) - 1 else "├── "
            icon = "📁 " if entry.is_dir() else "📄 "
            lines.append(f"{prefix}{connector}{icon}{entry.name}")
            if entry.is_dir():
                ext = "    " if i == len(entries) - 1 else "│   "
                walk(entry, depth + 1, prefix + ext)

    lines.append(f"📁 {root_path.name}/")
    walk(root_path, 1)
    return "\n".join(lines)


def get_git_context() -> dict:
    ctx = {"available": False}
    try:
        branch = subprocess.check_output(
            ["git", "branch", "--show-current"], stderr=subprocess.DEVNULL
        ).decode().strip()
        status = subprocess.check_output(
            ["git", "status", "--short"], stderr=subprocess.DEVNULL
        ).decode().strip()
        diff = subprocess.check_output(
            ["git", "diff", "--stat", "HEAD"], stderr=subprocess.DEVNULL
        ).decode().strip()
        last_commits = subprocess.check_output(
            ["git", "log", "--oneline", "-5"], stderr=subprocess.DEVNULL
        ).decode().strip()
        ctx = {
            "available": True,
            "branch": branch,
            "status": status,
            "diff_stat": diff,
            "recent_commits": last_commits,
        }
    except Exception:
        pass
    return ctx


def get_project_context(cwd: str = ".") -> str:
    """Build full context string for AI system prompt."""
    parts = []
    parts.append(f"Working directory: {Path(cwd).resolve()}")
    parts.append(f"OS: {os.name} / {os.uname().sysname if hasattr(os, 'uname') else 'unknown'}")

    # file tree
    parts.append("\n--- FILE TREE ---")
    parts.append(get_file_tree(cwd))

    # git
    git = get_git_context()
    if git["available"]:
        parts.append("\n--- GIT ---")
        parts.append(f"Branch: {git['branch']}")
        if git["status"]:
            parts.append(f"Changed files:\n{git['status']}")
        if git["recent_commits"]:
            parts.append(f"Recent commits:\n{git['recent_commits']}")

    # package.json or pyproject.toml detection
    for manifest in ["package.json", "pyproject.toml", "requirements.txt", "Cargo.toml", "go.mod"]:
        mpath = Path(cwd) / manifest
        if mpath.exists():
            try:
                content = mpath.read_text()[:1500]
                parts.append(f"\n--- {manifest} ---\n{content}")
            except Exception:
                pass
            break

    return "\n".join(parts)
