import { describe, expect, it } from 'vitest';
import {
  levenshtein,
  suggestToolName,
  formatUnknownToolError,
} from '../inference/tool-suggestions.js';

describe('levenshtein', () => {
  it('returns 0 for identical strings', () => {
    expect(levenshtein('view_file', 'view_file')).toBe(0);
  });

  it('returns the length when one string is empty', () => {
    expect(levenshtein('', 'view_file')).toBe(9);
    expect(levenshtein('view_file', '')).toBe(9);
  });

  it('computes a small distance for a single-character substitution', () => {
    expect(levenshtein('cat', 'bat')).toBe(1);
  });

  it('computes a known case: read_file → view_file is 4', () => {
    expect(levenshtein('read_file', 'view_file')).toBe(4);
  });
});

describe('suggestToolName (v1.13.16)', () => {
  const tools = [
    'view_file',
    'list_dir',
    'grep',
    'find_files',
    'view_truncated_output',
    'ask_user_input',
    'web_search',
  ];

  it('suggests the closest match when distance is small', () => {
    expect(suggestToolName('view_files', tools)).toBe('view_file');
  });

  it('suggests via substring match when distance alone would miss', () => {
    expect(suggestToolName('file', tools)).toBe('view_file');
  });

  it('returns null when nothing is close', () => {
    expect(suggestToolName('xxxx_yyyy_zzzz', tools)).toBeNull();
  });

  it('is case-insensitive in the distance check', () => {
    expect(suggestToolName('VIEW_FILE', tools)).toBe('view_file');
  });
});

describe('formatUnknownToolError (v1.13.16)', () => {
  const tools = ['view_file', 'list_dir', 'grep', 'find_files'];

  it('includes the wrong name and the available tools list', () => {
    const msg = formatUnknownToolError('read_file', tools);
    expect(msg).toContain("Tool 'read_file' not found");
    expect(msg).toContain('Available tools:');
    expect(msg).toContain('view_file');
    expect(msg).toContain('find_files');
  });

  it('includes a suggestion when the drifted name is within threshold', () => {
    const msg = formatUnknownToolError('view_files', tools);
    expect(msg).toContain('Did you mean: view_file?');
  });

  it('omits the suggestion clause when no tool is close enough', () => {
    const msg = formatUnknownToolError('zzzzzzz', tools);
    expect(msg).toContain("Tool 'zzzzzzz' not found");
    expect(msg).toContain('Available tools:');
    expect(msg).not.toContain('Did you mean');
  });

  it('does not suggest view_file for the read_file drift case (distance is 4, over threshold)', () => {
    const msg = formatUnknownToolError('read_file', tools);
    expect(msg).not.toContain('Did you mean');
  });
});
