# -*- coding: utf-8 -*-
"""CJ DiffCommand Git 差异展示（Phase 8 Tier 2）

借鉴 zhikuncode DiffCommand.java（69 行）：
- /diff [staged] 显示 Git 工作区或暂存区差异
- 检测当前目录是否 git 仓库
- 截断 10000 字符避免刷屏
- 同时返回 stat 摘要

集成点：main.py handle_slash_command 注册 /diff。
"""
import subprocess
from pathlib import Path
from typing import Tuple

MAX_DIFF_OUTPUT_CHARS = 10000  # 单次输出最大字符数


def is_git_repo(working_dir: str) -> bool:
    """检测指定目录是否是 git 仓库。

    Args:
        working_dir: 工作目录路径

    Returns:
        True=是 git 仓库，False=不是
    """
    try:
        result = subprocess.run(
            ["git", "rev-parse", "--is-inside-work-tree"],
            cwd=working_dir,
            capture_output=True,
            text=True,
            encoding="utf-8",
            errors="replace",
            timeout=5,
        )
        return result.returncode == 0 and (result.stdout or "").strip() == "true"
    except (subprocess.SubprocessError, OSError):
        return False


def run_git_diff(working_dir: str, staged: bool = False) -> Tuple[str, str]:
    """执行 git diff 命令。

    Args:
        working_dir: 工作目录路径
        staged: True=暂存区差异（--cached），False=工作区差异

    Returns:
        (stdout, stderr) 元组（解码失败时为空字符串）
    """
    cmd = ["git", "diff", "--cached"] if staged else ["git", "diff"]
    result = subprocess.run(
        cmd,
        cwd=working_dir,
        capture_output=True,
        text=True,
        encoding="utf-8",
        errors="replace",
        timeout=10,
    )
    return result.stdout or "", result.stderr or ""


def run_git_stat(working_dir: str) -> Tuple[str, str]:
    """执行 git diff --stat 命令获取摘要。

    Args:
        working_dir: 工作目录路径

    Returns:
        (stdout, stderr) 元组（解码失败时为空字符串）
    """
    result = subprocess.run(
        ["git", "diff", "--stat"],
        cwd=working_dir,
        capture_output=True,
        text=True,
        encoding="utf-8",
        errors="replace",
        timeout=10,
    )
    return result.stdout or "", result.stderr or ""


def handle_diff(working_dir: str, staged: bool = False) -> str:
    """/diff 命令处理：显示 Git 差异。

    Args:
        working_dir: 工作目录路径
        staged: True=显示暂存区差异，False=显示工作区差异

    Returns:
        可读的 diff 输出字符串（含 stat 摘要）
    """
    # 安全检查：禁止在系统目录执行
    try:
        resolved = str(Path(working_dir).resolve())
        # Windows 系统目录
        system_dirs = {"C:\\", "C:\\Windows", "C:\\Program Files", "C:\\Program Files (x86)"}
        if resolved in system_dirs or resolved.endswith(":\\"):
            return "[ERR] 禁止在系统目录执行 /diff"
    except (OSError, ValueError):
        pass

    if not is_git_repo(working_dir):
        return "[INFO] 当前目录不是 Git 仓库"

    diff_out, _ = run_git_diff(working_dir, staged=staged)
    stat_out, _ = run_git_stat(working_dir)

    if not diff_out.strip():
        return "[INFO] 工作区无变更（如需暂存区差异请用 /diff staged）"

    # 截断保护
    truncated = False
    if len(diff_out) > MAX_DIFF_OUTPUT_CHARS:
        diff_out = diff_out[:MAX_DIFF_OUTPUT_CHARS] + "\n...[截断，仅显示前 10000 字符]"
        truncated = True

    lines = []
    if stat_out.strip():
        lines.append("```")
        lines.append(stat_out.strip())
        lines.append("```")
        lines.append("")
    lines.append("```diff")
    lines.append(diff_out.rstrip())
    lines.append("```")
    if truncated:
        lines.append("")
        lines.append("[提示] 输出已截断，完整差异请用 `git diff > diff.txt` 转存到文件")
    return "\n".join(lines)
