import { z } from 'zod';
import { makeCodecontextTool } from './factory.js';

export const GetSemanticNeighborhoodsInput = z.object({
  file_path: z.string().trim().optional(),
  include_basic: z.boolean().optional(),
  include_quality: z.boolean().optional(),
  max_results: z.number().int().positive().optional(),
});
export type GetSemanticNeighborhoodsInputT = z.infer<typeof GetSemanticNeighborhoodsInput>;

const DESCRIPTION =
  'Returns semantic neighborhoods — clusters of related files derived from git co-change patterns and import structure. ' +
  'Use when you want to find code that "belongs together" with a given file without enumerating imports manually. ' +
  'Tree-sitter coverage: full for JS/Python/Java/Go/Rust/C++. TypeScript is approximate. ' +
  'PHP and SQL are not supported.';

const DEFAULT_MAX_RESULTS = 10;

const { toolDef: getSemanticNeighborhoods, execute: executeGetSemanticNeighborhoods } =
  makeCodecontextTool<GetSemanticNeighborhoodsInputT>({
    name: 'get_semantic_neighborhoods',
    schema: GetSemanticNeighborhoodsInput,
    description: DESCRIPTION,
    jsonParameters: {
      type: 'object',
      properties: {
        file_path: {
          type: 'string',
          description: 'Anchor file for the neighborhood query. Omit for a project-wide view.',
        },
        include_basic: {
          type: 'boolean',
          description: 'Include the basic (import-based) neighborhood. Default true.',
        },
        include_quality: {
          type: 'boolean',
          description: 'Include code-quality metrics for the neighborhood. Default false.',
        },
        max_results: {
          type: 'integer',
          description: `Cap on neighborhoods returned. Defaults to ${DEFAULT_MAX_RESULTS}.`,
        },
      },
      additionalProperties: false,
    },
    mapArgs: (input) => {
      const args: Record<string, unknown> = {
        max_results: input.max_results ?? DEFAULT_MAX_RESULTS,
      };
      if (input.file_path) args['file_path'] = input.file_path;
      if (input.include_basic !== undefined) args['include_basic'] = input.include_basic;
      if (input.include_quality !== undefined) args['include_quality'] = input.include_quality;
      return args;
    },
  });

export { getSemanticNeighborhoods, executeGetSemanticNeighborhoods };
