import type { PilotDeckToolDefinition } from "../protocol/types.js";
import { PilotDeckToolRuntimeError } from "../protocol/errors.js";
import { resolvePilotDeckWorkspacePath } from "./filesystem/pathSafety.js";
import { ripgrepFiles } from "./filesystem/ripgrepFiles.js";

export type GlobInput = {
  pattern: string;
  path?: string;
  limit?: number;
};

export function createGlobTool(): PilotDeckToolDefinition<GlobInput> {
  return {
    name: "glob",
    aliases: ["Glob"],
    description:
      "Fast file pattern matching tool scoped to the workspace.\n\nUsage:\n- Supports glob patterns like \"**/*.js\" or \"src/**/*.ts\".\n- Use this tool when you need to find files by name patterns.\n- Provide the optional path parameter to restrict the search to a subdirectory inside the workspace.\n- Returns matching file paths in stable sorted order.\n- Use this tool to narrow down candidate files before reading or editing them.",
    kind: "filesystem",
    inputSchema: {
      type: "object",
      required: ["pattern"],
      additionalProperties: false,
      properties: {
        pattern: {
          type: "string",
          description: "The glob pattern to match files against.",
        },
        path: {
          type: "string",
          description:
            "The directory to search in. If not specified, the workspace root will be used. Omit this field to use the default directory. Must resolve to a directory inside the workspace if provided.",
        },
        limit: {
          type: "integer",
          description:
            "Maximum number of file paths to return. This is a PilotDeck-specific output cap; defaults to 1000. Results remain stable and sorted before truncation.",
        },
      },
    },
    maxResultBytes: 200_000,
    isReadOnly: () => true,
    isConcurrencySafe: () => true,
    execute: async (input, context) => {
      const resolved = resolvePilotDeckWorkspacePath(input.path ?? ".", context, { mustExist: true });
      if (!resolved.ok) {
        throw new PilotDeckToolRuntimeError(resolved.error.code, resolved.error.message, resolved.error.details);
      }

      const result = await ripgrepFiles({
        cwd: resolved.absolutePath,
        pattern: input.pattern,
        limit: input.limit,
        env: context.env,
        signal: context.abortSignal,
      });
      const workspacePrefix = resolved.relativePath === "." ? "" : `${resolved.relativePath}/`;
      const workspaceFiles = result.files.map((file) => `${workspacePrefix}${file}`);

      return {
        content: [{ type: "text", text: workspaceFiles.join("\n") }],
        data: {
          files: workspaceFiles,
          count: result.count,
          truncated: result.truncated,
        },
        metadata: { truncated: result.truncated },
      };
    },
  };
}