import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
import { writeFileSync } from 'node:fs';
import { tmpdir } from 'node:os';
import { join } from 'node:path';
import { buildPiProviderEntry } from '../pi-config-sync.js';
import { loadLlamaProviders } from '../llama-providers.js';

describe('buildPiProviderEntry', () => {
  const fetchMock = vi.fn();

  beforeEach(() => {
    vi.stubGlobal('fetch', fetchMock);
    fetchMock.mockResolvedValue(
      new Response(JSON.stringify({ data: [{ id: 'qwen3.6-35b' }] }), {
        status: 200,
        headers: { 'content-type': 'application/json' },
      }),
    );
    const file = {
      defaultProvider: 'sam-desktop',
      providers: [
        { id: 'sam-desktop', label: 'Sam Desktop', baseUrl: 'http://a.test:8401', kind: 'llama-swap' },
      ],
    };
    const path = join(tmpdir(), `llama-providers-pi-${Math.random().toString(36).slice(2)}.json`);
    writeFileSync(path, JSON.stringify(file), 'utf8');
    loadLlamaProviders(path, 'http://legacy.test:8080');
  });

  afterEach(() => {
    vi.unstubAllGlobals();
  });

  it('emits a Pi-routable provider with gateway baseUrl and composite model ids', async () => {
    const entry = await buildPiProviderEntry('http://127.0.0.1:9502');
    expect(entry.baseUrl).toBe('http://127.0.0.1:9502/v1');
    expect(entry.api).toBe('openai-completions');
    expect(entry.models?.map((m) => m.id)).toEqual(['sam-desktop/qwen3.6-35b']);
    expect(entry.models?.[0]?.contextWindow).toBeGreaterThan(0);
    expect(entry.models?.[0]?.cost).toEqual({ input: 0, output: 0, cacheRead: 0, cacheWrite: 0 });
  });

  it('preserves hand-tuned per-model overrides on re-sync', async () => {
    const existing = {
      baseUrl: 'http://stale:1/v1',
      models: [
        {
          id: 'sam-desktop/qwen3.6-35b',
          name: 'Old Name',
          contextWindow: 262_144,
          maxTokens: 65_536,
        },
      ],
    };
    const entry = await buildPiProviderEntry('http://127.0.0.1:9502', existing);
    expect(entry.baseUrl).toBe('http://127.0.0.1:9502/v1'); // ours wins
    const m = entry.models?.[0];
    expect(m?.contextWindow).toBe(262_144); // hand-tuned values preserved
    expect(m?.maxTokens).toBe(65_536);
  });
});
