// SPDX-FileCopyrightText: Amolith <amolith@secluded.site>
//
// SPDX-License-Identifier: GPL-3.0-or-later

import { Type } from "@sinclair/typebox";
import type { AgentTool } from "@mariozechner/pi-agent-core";
import simpleGit from "simple-git";
import { formatSize, truncateHead } from "../../../util/truncate.js";

// Trust boundary: refs and paths are passed directly to simple-git, which is
// scoped to the workspace. The user chose to clone this repo, so its contents
// are trusted. See AGENTS.md § Workspace Sandboxing.

const RefsSchema = Type.Object({
  type: Type.Union([
    Type.Literal("branches"),
    Type.Literal("tags"),
    Type.Literal("remotes"),
  ]),
});

export const createGitRefsTool = (workspacePath: string): AgentTool => ({
  name: "git_refs",
  label: "Git Refs",
  description: "List branches, tags, or remotes.",
  parameters: RefsSchema as any,
  execute: async (_toolCallId: string, params: any) => {
    const git = simpleGit(workspacePath);

    let raw: string;
    let baseDetails: Record<string, any> = {};

    if (params.type === "tags") {
      const tags = await git.tags();
      raw = tags.all.join("\n");
      baseDetails = { count: tags.all.length };
    } else if (params.type === "remotes") {
      raw = await git.raw(["branch", "-r"]);
    } else {
      raw = await git.raw(["branch", "-a"]);
    }

    const truncation = truncateHead(raw);
    let text = truncation.content;
    if (truncation.truncated) {
      text += `\n\n[truncated: showing ${truncation.outputLines} of ${truncation.totalLines} lines (${formatSize(truncation.outputBytes)} of ${formatSize(truncation.totalBytes)})]`;
    }

    return {
      content: [{ type: "text", text }],
      details: { ...baseDetails, ...(truncation.truncated ? { truncation } : {}) },
    };
  },
});
