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

export const SearchSymbolsInput = z.object({
  query: z.string().min(1),
  file_type: z.string().optional(),
  symbol_type: z.string().optional(),
  framework_type: z.string().optional(),
  limit: z.number().int().positive().optional(),
});
export type SearchSymbolsInputT = z.infer<typeof SearchSymbolsInput>;

const DESCRIPTION =
  'Search for symbols (functions, classes, methods, types) across the codebase by name fragment. ' +
  'Filter by file_type, symbol_type, or framework_type to narrow. ' +
  'Tree-sitter coverage: full for JS/Python/Java/Go/Rust/C++. TypeScript symbols are approximate. ' +
  'PHP and SQL are not supported — fall back to grep for those.';

const DEFAULT_LIMIT = 20;

const { toolDef: searchSymbols, execute: executeSearchSymbols } =
  makeCodecontextTool<SearchSymbolsInputT>({
    name: 'search_symbols',
    schema: SearchSymbolsInput,
    description: DESCRIPTION,
    jsonParameters: {
      type: 'object',
      properties: {
        query: { type: 'string', description: 'Substring or name fragment to match.' },
        file_type: {
          type: 'string',
          description: 'Filter by file extension or language (e.g. "ts", "py", "go").',
        },
        symbol_type: {
          type: 'string',
          description: 'Filter by kind: function|class|method|variable|type|interface.',
        },
        framework_type: {
          type: 'string',
          description: 'Filter by framework context (react|vue|svelte|…).',
        },
        limit: {
          type: 'integer',
          description: `Max matches to return. Defaults to ${DEFAULT_LIMIT}.`,
        },
      },
      required: ['query'],
      additionalProperties: false,
    },
    mapArgs: (input) => {
      const args: Record<string, unknown> = {
        query: input.query,
        limit: input.limit ?? DEFAULT_LIMIT,
      };
      if (input.file_type) args['file_type'] = input.file_type;
      if (input.symbol_type) args['symbol_type'] = input.symbol_type;
      if (input.framework_type) args['framework_type'] = input.framework_type;
      return args;
    },
  });

export { searchSymbols, executeSearchSymbols };
