import { fileURLToPath } from 'node:url';
import { describe, expect, test } from 'vitest';
import { generateFilesOnly } from '@/generate-file';
import { createAsyncAPI } from '@/server';
import path from 'node:path';

const cwd = fileURLToPath(new URL('./', import.meta.url));

function stringifyOutput(files: { path: string; content: string }[]) {
  return files
    .sort((a, b) => a.path.localeCompare(b.path))
    .map((file) => `## ${file.path}\n\n${file.content}`)
    .join('\n\n');
}

describe('Generate AsyncAPI documents', () => {
  test('Streetlights (Per Operation)', async () => {
    const out = await generateFilesOnly({
      input: createAsyncAPI({
        input: {
          streetlights: path.join(cwd, './fixtures/streetlights.yaml'),
        },
      }),
      per: 'operation',
    });

    expect(out).toHaveLength(2);
    expect(out).toMatchInlineSnapshot(`
      [
        {
          "content": "---
      title: Receive light measurement
      full: true
      _asyncapi:
        preload:
          - streetlights
        action: receive
        toc: []
        structuredData:
          headings: []
          contents: []
      ---

      {/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */}

      <AsyncAPIPage document="streetlights" operations={[{"id":"receiveLightMeasurement","action":"receive"}]} />",
          "path": "receiveLightMeasurement.mdx",
        },
        {
          "content": "---
      title: Send light measurement
      full: true
      _asyncapi:
        preload:
          - streetlights
        action: send
        toc: []
        structuredData:
          headings: []
          contents: []
      ---

      {/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */}

      <AsyncAPIPage document="streetlights" operations={[{"id":"sendLightMeasurement","action":"send"}]} />",
          "path": "sendLightMeasurement.mdx",
        },
      ]
    `);
  });

  test('Streetlights (Per Tag)', async () => {
    const out = await generateFilesOnly({
      input: createAsyncAPI({
        input: {
          streetlights: path.join(cwd, './fixtures/streetlights.yaml'),
        },
      }),
      per: 'tag',
    });

    expect(out).toMatchInlineSnapshot(`
      [
        {
          "content": "---
      title: Lighting
      full: true
      _asyncapi:
        preload:
          - streetlights
        toc:
          - depth: 2
            title: Send light measurement
            url: '#send-light-measurement'
        structuredData:
          headings:
            - content: Send light measurement
              id: send-light-measurement
          contents: []
      ---

      {/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */}

      <AsyncAPIPage document="streetlights" operations={[{"id":"sendLightMeasurement","action":"send"}]} showTitle />",
          "path": "lighting.mdx",
        },
      ]
    `);
  });

  test('Streetlights (Per File)', async () => {
    const out = await generateFilesOnly({
      input: createAsyncAPI({
        input: {
          streetlights: path.join(cwd, './fixtures/streetlights.yaml'),
        },
      }),
      per: 'file',
    });

    expect(out).toHaveLength(1);
    expect(out[0].path).toContain('streetlights');
    expect(stringifyOutput(out)).toMatchSnapshot();
  });

  test('throws error when no input files found', async () => {
    await expect(
      generateFilesOnly({
        input: createAsyncAPI({ input: {} }),
        per: 'file',
      }),
    ).rejects.toThrow();
  });
});
