// v1.12 Track B.2: codecontext wrapper — search_symbols.

import { z } from 'zod';
import type { ToolDef } from '../../tools.js';
import { callCodecontext, type CodecontextResponse } from '../../codecontext_client.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;

export async function executeSearchSymbols(
  input: SearchSymbolsInputT,
  projectPath: string,
  fetcher: typeof fetch = fetch,
): Promise<CodecontextResponse> {
  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 callCodecontext({ toolName: 'search_symbols', args, projectPath }, fetcher);
}

export const searchSymbols: ToolDef<SearchSymbolsInputT> = {
  name: 'search_symbols',
  description: DESCRIPTION,
  inputSchema: SearchSymbolsInput,
  jsonSchema: {
    type: 'function',
    function: {
      name: 'search_symbols',
      description: DESCRIPTION,
      parameters: {
        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,
      },
    },
  },
  async execute(input, projectRoot) {
    return await executeSearchSymbols(input, projectRoot);
  },
};
