// tests/background/webm-remux-deps.test.ts
//
// Plan 01-08 Task 1: SW-compatibility + presence contract for the two new
// runtime dependencies that the WebM remux pipeline rests on. Pins the
// architectural commitment that landed in CONTEXT.md amendment D-14-remux:
//   - `ts-ebml`  ^3.0.2 (MIT, parses each VideoSegment's EBML structure)
//   - `webm-muxer` ^5.1.4 (MIT, writes the single-EBML-headered output)
//
// Both libraries were surveyed in `.planning/debug/d13-multi-ebml-concat-
// unplayable.md` (Evidence/library-survey, lines 380-410). They are pure
// JS, pure ESM/CJS, and were grep-verified at survey time to contain no
// hard DOM-global references on the hot path. Chrome's service-worker
// runtime (where `remuxSegments()` will execute) does not provide
// `window` or `document`; this test pins that compat at the
// devDependency-import surface so a future bump that accidentally adds
// a DOM global is caught at test time rather than at runtime in a
// production SW.
//
// Test 1 asserts named-export presence (RED until `npm install` lands).
// Test 2 asserts both libraries load under default Node globals without
// referencing `window` or `document` synchronously at import time.
//
// Skip discipline: none — these are pure import-shape tests, no external
// binaries, no fixtures. Vitest's default Node environment is sufficient.

import { describe, it, expect, beforeEach, afterEach } from 'vitest';

interface GlobalSnapshot {
  window: unknown;
  document: unknown;
  hadWindow: boolean;
  hadDocument: boolean;
}

/**
 * Capture the current values of `window` and `document` on `globalThis`
 * so they can be restored after a test that deletes them. Vitest's
 * `vi.stubGlobal` is not used here because we want to assert the
 * absence of the globals at import time, not just stub them.
 *
 * @returns Snapshot the caller passes back to {@link restoreGlobals}.
 */
function snapshotGlobals(): GlobalSnapshot {
  const g = globalThis as unknown as Record<string, unknown>;
  return {
    window: g.window,
    document: g.document,
    hadWindow: 'window' in g,
    hadDocument: 'document' in g,
  };
}

/**
 * Restore the globals captured by {@link snapshotGlobals}. Idempotent.
 *
 * @param snap - Snapshot returned by {@link snapshotGlobals}.
 */
function restoreGlobals(snap: GlobalSnapshot): void {
  const g = globalThis as unknown as Record<string, unknown>;
  if (snap.hadWindow) {
    g.window = snap.window;
  } else {
    delete g.window;
  }
  if (snap.hadDocument) {
    g.document = snap.document;
  } else {
    delete g.document;
  }
}

describe('webm-remux dependencies (Plan 01-08 Task 1)', () => {
  it('exports Muxer + ArrayBufferTarget + Decoder', async () => {
    // Dynamic import so a missing package surfaces as a precise test
    // failure ("Cannot find module 'webm-muxer'") rather than a Vitest
    // collection error that hides which dependency is the cause.
    const webmMuxer = await import('webm-muxer');
    expect(webmMuxer.Muxer).toBeDefined();
    expect(webmMuxer.ArrayBufferTarget).toBeDefined();

    const tsEbml = await import('ts-ebml');
    expect(tsEbml.Decoder).toBeDefined();
  });

  describe('loads under default Node globals without DOM-global ReferenceErrors', () => {
    let snap: GlobalSnapshot;

    beforeEach(() => {
      snap = snapshotGlobals();
      const g = globalThis as unknown as Record<string, unknown>;
      delete g.window;
      delete g.document;
    });

    afterEach(() => {
      restoreGlobals(snap);
    });

    it('webm-muxer + ts-ebml do not throw on import when window/document are absent', async () => {
      // The Chrome service-worker runtime provides neither `window` nor
      // `document`. If either library's published dist references one
      // of these synchronously at module evaluation time (e.g. a UMD
      // wrapper falling through to `window`), the import below would
      // throw a ReferenceError and this test would fail with a clear
      // signal.
      //
      // ts-ebml's UMD wrapper does contain a `typeof window` check
      // with a `self`/`global` fallback per the d13 library survey
      // — `typeof` does NOT throw on undeclared identifiers per
      // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/typeof
      // so the fallback path resolves cleanly.
      //
      // webm-muxer is documented zero-DOM-ref.
      let webmMuxerError: unknown = null;
      try {
        await import('webm-muxer');
      } catch (e) {
        webmMuxerError = e;
      }
      expect(
        webmMuxerError,
        `webm-muxer threw at import time without window/document: ${String(webmMuxerError)}`,
      ).toBeNull();

      let tsEbmlError: unknown = null;
      try {
        await import('ts-ebml');
      } catch (e) {
        tsEbmlError = e;
      }
      expect(
        tsEbmlError,
        `ts-ebml threw at import time without window/document: ${String(tsEbmlError)}`,
      ).toBeNull();
    });
  });
});
