import { describe, expect, it } from 'vitest';
import {
  deserializeCapabilities,
  parseBuildConfiguration,
  parseCodecs,
  parseFilters,
  parseFormats,
  parseNamedComponents,
  serializeCapabilities,
} from '../../src/ffmpeg/capability-parser';

describe('FFmpeg capability parsing', () => {
  it('parses demuxer and muxer flags including aliases', () => {
    const parsed = parseFormats(`
 File formats:
  D. = Demuxing supported
  .E = Muxing supported
 DE  matroska,webm   Matroska / WebM
 D   mov,mp4,m4a     QuickTime / MOV
  E  mp3             MP3
`);
    expect(parsed.demuxers).toEqual(
      new Set(['matroska', 'webm', 'mov', 'mp4', 'm4a'])
    );
    expect(parsed.muxers).toEqual(new Set(['matroska', 'webm', 'mp3']));
  });

  it('parses codecs, encoders, filters and configuration flags', () => {
    const codecs = parseCodecs(`
 Codecs:
 D..... = Decoding supported
 .E.... = Encoding supported
 DEV.LS h264 H.264
 D.A.L. aac AAC
 .EV.L. vp9 VP9
`);
    expect(codecs.decoders).toEqual(new Set(['h264', 'aac']));
    expect(codecs.encoders).toEqual(new Set(['h264', 'vp9']));

    expect(
      parseNamedComponents(`
 Encoders:
 V..... libx264 H.264
 A..... aac AAC
`)
    ).toEqual(new Set(['libx264', 'aac']));

    expect(
      parseFilters(`
 Filters:
 ..C scale             V->V       Scale the input video size.
 T.. loudnorm          A->A       EBU R128 loudness normalization
 ... concat            N->N       Concatenate audio and video streams.
`)
    ).toEqual(new Set(['scale', 'loudnorm', 'concat']));

    expect(
      parseBuildConfiguration(
        'ffmpeg version x\nconfiguration: --enable-gpl --disable-doc'
      )
    ).toEqual(['--enable-gpl', '--disable-doc']);
  });

  it('serializes Set values for durable caches without losing data', () => {
    const original = {
      versionText: 'ffmpeg version n6.1',
      buildConfiguration: ['--enable-gpl'],
      demuxers: new Set(['mov']),
      muxers: new Set(['mp4']),
      decoders: new Set(['h264']),
      encoders: new Set(['libx264']),
      filters: new Set(['scale']),
    };
    expect(deserializeCapabilities(serializeCapabilities(original))).toEqual(
      original
    );
  });
});
