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

function loadFixture(
  providers: Array<{ id: string; label: string; baseUrl: string; kind?: string }>,
): string {
  const file = {
    defaultProvider: providers[0]!.id,
    providers: providers.map((p) => ({ ...p, kind: p.kind ?? 'llama-swap' })),
  };
  const path = join(tmpdir(), `llama-providers-test-${Math.random().toString(36).slice(2)}.json`);
  writeFileSync(path, JSON.stringify(file), 'utf8');
  return path;
}

describe('loadLlamaProviders', () => {
  afterEach(() => {
    vi.restoreAllMocks();
  });

  it('loads a valid providers file', () => {
    const path = loadFixture([
      { id: 'sam-desktop', label: 'Sam Desktop', baseUrl: 'http://100.101.41.16:8401' },
      { id: 'embedding', label: 'Embedding', baseUrl: 'http://100.90.172.55:8411' },
    ]);

    const result = loadLlamaProviders(path, 'http://legacy.test:8080');

    expect(result.providers).toHaveLength(2);
    expect(result.providers[0]!.id).toBe('sam-desktop');
    expect(result.providers[0]!.baseUrl).toBe('http://100.101.41.16:8401');
    expect(result.providers[1]!.id).toBe('embedding');
    expect(result.providers[1]!.baseUrl).toBe('http://100.90.172.55:8411');

    unlinkSync(path);
  });

  it('falls back to legacy when file is missing', () => {
    const warnSpy = vi.spyOn(console, 'warn').mockImplementation(() => {});

    const result = loadLlamaProviders('/nonexistent/path.json', 'http://legacy.test:8080');

    expect(result.providers).toHaveLength(1);
    expect(result.providers[0]!.id).toBe('llama-swap');
    expect(result.providers[0]!.baseUrl).toBe('http://legacy.test:8080');

    warnSpy.mockRestore();
  });

  it('falls back to legacy when path is undefined', () => {
    const result = loadLlamaProviders(undefined, 'http://legacy.test:8080');

    expect(result.providers).toHaveLength(1);
    expect(result.providers[0]!.id).toBe('llama-swap');
    expect(result.providers[0]!.baseUrl).toBe('http://legacy.test:8080');
  });

  it('falls back to legacy when JSON is invalid', () => {
    const path = join(tmpdir(), `llama-providers-bad-${Math.random().toString(36).slice(2)}.json`);
    writeFileSync(path, '{not valid json', 'utf8');
    const errorSpy = vi.spyOn(console, 'error').mockImplementation(() => {});

    const result = loadLlamaProviders(path, 'http://legacy.test:8080');

    expect(result.providers).toHaveLength(1);
    expect(result.providers[0]!.id).toBe('llama-swap');

    errorSpy.mockRestore();
    unlinkSync(path);
  });
});

describe('getLlamaProviders', () => {
  it('returns cached result after load', () => {
    loadLlamaProviders(undefined, 'http://test.example:9999');
    const cached = getLlamaProviders();
    expect(cached.providers[0]!.baseUrl).toBe('http://test.example:9999');
  });

  it('returns legacy fallback when nothing loaded', () => {
    // This tests the fallback when cached is null.
    // Since loadLlamaProviders always sets cached, we test the default URL.
    const result = getLlamaProviders();
    expect(result).toBeDefined();
    expect(result.providers.length).toBeGreaterThanOrEqual(1);
  });
});

describe('resolveProviderBaseUrl', () => {
  it('resolves baseUrl for a known provider', () => {
    loadLlamaProviders(undefined, 'http://test.example:9999');
    expect(resolveProviderBaseUrl('llama-swap')).toBe('http://test.example:9999');
  });

  it('returns null for unknown provider', () => {
    loadLlamaProviders(undefined, 'http://test.example:9999');
    expect(resolveProviderBaseUrl('nonexistent')).toBeNull();
  });

  it('resolves correct URLs for both seeded providers', () => {
    const path = loadFixture([
      { id: 'sam-desktop', label: 'Sam Desktop', baseUrl: 'http://100.101.41.16:8401' },
      { id: 'embedding', label: 'Embedding', baseUrl: 'http://100.90.172.55:8411' },
    ]);
    loadLlamaProviders(path, 'http://legacy.test:8080');

    expect(resolveProviderBaseUrl('sam-desktop')).toBe('http://100.101.41.16:8401');
    expect(resolveProviderBaseUrl('embedding')).toBe('http://100.90.172.55:8411');

    unlinkSync(path);
  });
});
