import { describe, it, expect } from 'vitest';
import { SyntheticClient } from './synthetic.js';
import type { ChatRequest } from './types.js';

function makeRequest(text: string): ChatRequest {
  return {
    messages: [{ role: 'user', content: text }],
  };
}

describe('SyntheticClient', () => {
  it('echoes the last user message by default', async () => {
    const client = new SyntheticClient({ model: 'echo' });
    const res = await client.chat(makeRequest('hello'));
    expect(res.content).toBe('hello');
    expect(res.stopReason).toBe('end_turn');
    expect(res.toolCalls).toBeUndefined();
    expect(res.usage.inputTokens).toBeGreaterThan(0);
    expect(res.usage.outputTokens).toBeGreaterThan(0);
  });

  it('supports fixed responses via model=fixed:<text>', async () => {
    const client = new SyntheticClient({ model: 'fixed:ok' });
    const res = await client.chat(makeRequest('ignored'));
    expect(res.content).toBe('ok');
    expect(res.stopReason).toBe('end_turn');
  });

  it('supports tool calls via @tool directive', async () => {
    const client = new SyntheticClient({ model: 'echo' });
    const res = await client.chat(makeRequest('@tool memory.read {"namespace":"global"}'));
    expect(res.stopReason).toBe('tool_use');
    expect(res.content).toBe('');
    expect(res.toolCalls?.length).toBe(1);
    expect(res.toolCalls?.[0]?.name).toBe('memory.read');
    expect(res.toolCalls?.[0]?.args).toEqual({ namespace: 'global' });
  });

  it('streams content + done', async () => {
    const client = new SyntheticClient({ model: 'fixed:stream-me' });
    const events: string[] = [];
    for await (const ev of client.chatStream!(makeRequest('x'))) {
      events.push(ev.type);
    }
    expect(events).toEqual(['content', 'done']);
  });

  it('streams tool_use + done for @tool directives', async () => {
    const client = new SyntheticClient({ model: 'echo' });
    const types: string[] = [];
    const toolNames: string[] = [];
    for await (const ev of client.chatStream!(makeRequest('@tool file.read {"path":"README.md"}'))) {
      types.push(ev.type);
      if (ev.type === 'tool_use' && ev.toolCall) {
        toolNames.push(ev.toolCall.name);
      }
    }
    expect(types).toEqual(['tool_use', 'done']);
    expect(toolNames).toEqual(['file.read']);
  });
});

