/**
 * Adapter-selection regression guards.
 *
 * TRACES: UR-003, UR-004 | DR-150 | UT-149
 *
 * The selection rule has two inputs and one hard safety property:
 *
 *   - Rust says which backend the platform has (`backendKind`).
 *   - The user opts in with `experimentalNativeVideo`.
 *   - **The flag off must force HTML5 even when Rust says native.** That is the
 *     regression guard: a broken spike must not be able to ship as the default.
 *
 * These are pure functions, so the whole matrix is testable without a device.
 */

import { describe, expect, it } from "vitest";
import { createAdapter } from "./index";
import { Html5PlayerAdapter } from "./html5Adapter";
import { NativePlayerAdapter } from "./nativeAdapter";
import type { AdapterHost } from "./types";

const host: AdapterHost = {
  reportState: () => {},
  reportPosition: () => {},
  reportEnded: () => {},
} as unknown as AdapterHost;

const bridge = {
  getElement: () => null,
} as any;

describe("createAdapter", () => {
  it("returns the native adapter when Rust says native and the flag is on", () => {
    const adapter = createAdapter({
      backendKind: "native",
      host,
      bridge,
      experimentalNativeVideo: true,
    });
    expect(adapter).toBeInstanceOf(NativePlayerAdapter);
    expect(adapter.kind).toBe("native");
  });

  // The regression guard: the flag is a suppressor, so off must beat Rust.
  it("forces HTML5 when the flag is off even though Rust says native", () => {
    const adapter = createAdapter({
      backendKind: "native",
      host,
      bridge,
      experimentalNativeVideo: false,
    });
    expect(adapter).toBeInstanceOf(Html5PlayerAdapter);
    expect(adapter.kind).toBe("html5");
  });

  it("returns the HTML5 adapter when Rust says html5 and the flag is off", () => {
    const adapter = createAdapter({
      backendKind: "html5",
      host,
      bridge,
      experimentalNativeVideo: false,
    });
    expect(adapter).toBeInstanceOf(Html5PlayerAdapter);
  });

  // The flag must never *promote* a platform Rust said has no native backend
  // (e.g. Linux, where WebKitGTK cannot composite a surface behind the webview).
  it("stays on HTML5 when Rust says html5 even with the flag on", () => {
    const adapter = createAdapter({
      backendKind: "html5",
      host,
      bridge,
      experimentalNativeVideo: true,
    });
    expect(adapter).toBeInstanceOf(Html5PlayerAdapter);
  });

  it("defaults to HTML5 when the flag is omitted entirely", () => {
    const adapter = createAdapter({ backendKind: "native", host, bridge });
    expect(adapter).toBeInstanceOf(Html5PlayerAdapter);
  });

  it("requires a bridge for the HTML5 adapter", () => {
    expect(() =>
      createAdapter({ backendKind: "html5", host, experimentalNativeVideo: false })
    ).toThrow(/bridge/i);
  });

  // The native adapter owns no DOM element, so it must not demand a bridge.
  it("does not require a bridge for the native adapter", () => {
    expect(() =>
      createAdapter({ backendKind: "native", host, experimentalNativeVideo: true })
    ).not.toThrow();
  });
});
