'use strict';

const { MpjpegParser } = require('../src/cameraSwitch');

// Baut ein FFmpeg-`-f mpjpeg`-Paket: Boundary + Header (Content-Length) + Body + CRLF.
function packet(jpeg) {
  return Buffer.concat([
    Buffer.from(`--frame\r\nContent-Type: image/jpeg\r\nContent-Length: ${jpeg.length}\r\n\r\n`, 'latin1'),
    jpeg,
    Buffer.from('\r\n', 'latin1'),
  ]);
}

describe('MpjpegParser', () => {
  test('ein Frame', () => {
    const frames = [];
    const p = new MpjpegParser((f) => frames.push(f));
    const jpeg = Buffer.from([0xFF, 0xD8, 1, 2, 3, 0xFF, 0xD9]);
    p.push(packet(jpeg));
    expect(frames).toHaveLength(1);
    expect(frames[0].equals(jpeg)).toBe(true);
  });

  test('mehrere Frames in einem Chunk', () => {
    const frames = [];
    const p = new MpjpegParser((f) => frames.push(f));
    const a = Buffer.from([0xFF, 0xD8, 1]);
    const b = Buffer.from([0xFF, 0xD8, 2, 3, 4]);
    p.push(Buffer.concat([packet(a), packet(b)]));
    expect(frames).toHaveLength(2);
    expect(frames[0].equals(a)).toBe(true);
    expect(frames[1].equals(b)).toBe(true);
  });

  test('über Chunk-Grenze gesplittetes Frame', () => {
    const frames = [];
    const p = new MpjpegParser((f) => frames.push(f));
    const jpeg = Buffer.from([10, 20, 30, 40, 50]);
    const pkt = packet(jpeg);
    p.push(pkt.subarray(0, 6));   // mitten im Header
    expect(frames).toHaveLength(0);
    p.push(pkt.subarray(6));      // Rest
    expect(frames).toHaveLength(1);
    expect(frames[0].equals(jpeg)).toBe(true);
  });

  test('Body über mehrere Chunks', () => {
    const frames = [];
    const p = new MpjpegParser((f) => frames.push(f));
    const jpeg = Buffer.from([1, 2, 3, 4, 5, 6, 7, 8]);
    const pkt = packet(jpeg);
    const cut = pkt.length - 5; // mitten im Body trennen
    p.push(pkt.subarray(0, cut));
    expect(frames).toHaveLength(0);
    p.push(pkt.subarray(cut));
    expect(frames).toHaveLength(1);
    expect(frames[0].equals(jpeg)).toBe(true);
  });
});
