#!/usr/bin/env node

// src/tools/git-context.ts
import { execSync } from "child_process";
import { existsSync } from "fs";
import { join } from "path";
function runGit(cmd, cwd) {
  try {
    return execSync(`git ${cmd}`, {
      cwd,
      encoding: "utf-8",
      stdio: ["pipe", "pipe", "pipe"],
      timeout: 5e3
    }).trim();
  } catch {
    return null;
  }
}
function getGitRoot(cwd = process.cwd()) {
  return runGit("rev-parse --show-toplevel", cwd);
}
function getGitContext(cwd = process.cwd()) {
  if (!existsSync(join(cwd, ".git"))) {
    const result = runGit("rev-parse --git-dir", cwd);
    if (!result) return null;
  }
  const branch = runGit("rev-parse --abbrev-ref HEAD", cwd);
  if (!branch) return null;
  const statusOutput = runGit("status --porcelain", cwd) ?? "";
  const statusLines = statusOutput ? statusOutput.split("\n").filter(Boolean) : [];
  const stagedFiles = [];
  const changedFiles = [];
  for (const line of statusLines) {
    const xy = line.slice(0, 2);
    const file = line.slice(3).trim();
    const indexStatus = xy[0];
    const workStatus = xy[1];
    if (indexStatus && indexStatus !== " " && indexStatus !== "?") {
      stagedFiles.push(`${indexStatus} ${file}`);
    }
    if (workStatus && workStatus !== " ") {
      changedFiles.push(`${workStatus} ${file}`);
    }
  }
  const logOutput = runGit("log --oneline -3", cwd) ?? "";
  const recentCommits = logOutput ? logOutput.split("\n").filter(Boolean) : [];
  const unpushedOutput = runGit("log @{u}..HEAD --oneline", cwd);
  const hasUnpushed = unpushedOutput !== null && unpushedOutput.trim().length > 0;
  return {
    branch,
    changedFiles,
    stagedFiles,
    recentCommits,
    hasUnpushed
  };
}
function formatGitContextForPrompt(ctx) {
  const lines = ["# Git Repository Status", ""];
  lines.push(`- **Branch**: \`${ctx.branch}\``);
  if (ctx.stagedFiles.length > 0) {
    lines.push(`- **Staged** (${ctx.stagedFiles.length} files):`);
    for (const f of ctx.stagedFiles.slice(0, 10)) {
      lines.push(`  - ${f}`);
    }
    if (ctx.stagedFiles.length > 10) {
      lines.push(`  - ... and ${ctx.stagedFiles.length - 10} more`);
    }
  }
  if (ctx.changedFiles.length > 0) {
    lines.push(`- **Modified** (${ctx.changedFiles.length} files):`);
    for (const f of ctx.changedFiles.slice(0, 10)) {
      lines.push(`  - ${f}`);
    }
    if (ctx.changedFiles.length > 10) {
      lines.push(`  - ... and ${ctx.changedFiles.length - 10} more`);
    }
  }
  if (ctx.stagedFiles.length === 0 && ctx.changedFiles.length === 0) {
    lines.push("- **Working tree**: clean");
  }
  if (ctx.recentCommits.length > 0) {
    lines.push("- **Recent commits**:");
    for (const c of ctx.recentCommits) {
      lines.push(`  - ${c}`);
    }
  }
  if (ctx.hasUnpushed) {
    lines.push("- \u26A0\uFE0F Has unpushed commits");
  }
  return lines.join("\n");
}

export {
  getGitRoot,
  getGitContext,
  formatGitContextForPrompt
};
