/**
 * AnthropicProvider — transport-error surfacing (parity with OpenAiProvider).
 *
 * A 404 "model not found" (OAuth-gated key on an unavailable model) or a 401
 * must reject with the status + body, not parse the error body as an empty
 * completion (which the gate then misreports as "did not contain valid JSON").
 */
import { describe, it, expect, beforeEach, vi } from 'vitest';

let mockStatus = 200;
let mockBody = JSON.stringify({ content: [{ type: 'text', text: 'ok' }], usage: {}, stop_reason: 'end_turn' });

vi.mock('node:https', () => {
  const request = vi.fn((_opts: unknown, cb?: unknown) => {
    const res = {
      statusCode: mockStatus,
      on: (event: string, handler: (d?: unknown) => void) => {
        if (event === 'data') handler(Buffer.from(mockBody));
        if (event === 'end') handler();
        return res;
      },
    };
    if (typeof cb === 'function') (cb as (r: unknown) => void)(res);
    return { on: vi.fn().mockReturnThis(), write: vi.fn(), end: vi.fn() };
  });
  return { default: { request }, request };
});

const { AnthropicProvider } = await import('../src/providers/anthropic.js');

describe('AnthropicProvider transport handling', () => {
  beforeEach(() => {
    mockStatus = 200;
    mockBody = JSON.stringify({ content: [{ type: 'text', text: 'ok' }], usage: {}, stop_reason: 'end_turn' });
  });

  it('rejects on HTTP 404 (model not found) instead of masking it as bad JSON', async () => {
    mockStatus = 404;
    mockBody = JSON.stringify({ type: 'error', error: { type: 'not_found_error', message: 'model: claude-opus-4' } });
    const p = new AnthropicProvider({ apiKey: 'sk-ant-oat01-x' });
    await expect(
      p.complete({ messages: [{ role: 'user', content: 'hi' }], maxTokens: 8 }),
    ).rejects.toThrow(/Anthropic HTTP 404/);
  });

  it('still returns the completion on 200', async () => {
    const p = new AnthropicProvider({ apiKey: 'sk-ant-oat01-x' });
    const r = await p.complete({ messages: [{ role: 'user', content: 'hi' }], maxTokens: 8 });
    expect(r.content).toBe('ok');
  });
});
