import assert from "node:assert/strict";
import test from "node:test";
import {
  MAX_BOOK_BYTES,
  validateBookFile,
} from "../../lib/domain/file-validation.ts";

const pdfHeader = new TextEncoder().encode("%PDF-1.7\n");
const epubHeader = Uint8Array.from([0x50, 0x4b, 0x03, 0x04, 0x14, 0x00]);

test("accepts DRM-free PDF and EPUB signatures up to 200 MB", () => {
  assert.deepEqual(
    validateBookFile({
      name: "双语读本.pdf",
      size: MAX_BOOK_BYTES,
      mimeType: "application/pdf",
      header: pdfHeader,
    }),
    { format: "pdf" },
  );

  assert.deepEqual(
    validateBookFile({
      name: "novel.EPUB",
      size: 42,
      mimeType: "application/epub+zip",
      header: epubHeader,
    }),
    { format: "epub" },
  );
});

test("rejects empty, oversized, unsupported, and disguised files", () => {
  assert.throws(
    () => validateBookFile({ name: "empty.pdf", size: 0, mimeType: "application/pdf", header: pdfHeader }),
    (error) => error.code === "empty_file",
  );
  assert.throws(
    () => validateBookFile({ name: "huge.pdf", size: MAX_BOOK_BYTES + 1, mimeType: "application/pdf", header: pdfHeader }),
    (error) => error.code === "file_too_large",
  );
  assert.throws(
    () => validateBookFile({ name: "notes.txt", size: 9, mimeType: "text/plain", header: pdfHeader }),
    (error) => error.code === "unsupported_extension",
  );
  assert.throws(
    () => validateBookFile({ name: "fake.pdf", size: 9, mimeType: "application/pdf", header: epubHeader }),
    (error) => error.code === "signature_mismatch",
  );
});

test("rejects encrypted PDF and protected EPUB signals without attempting bypass", () => {
  assert.throws(
    () => validateBookFile({ name: "locked.pdf", size: 99, mimeType: "application/pdf", header: pdfHeader, encrypted: true }),
    (error) => error.code === "drm_or_encrypted",
  );
  assert.throws(
    () => validateBookFile({ name: "locked.epub", size: 99, mimeType: "application/epub+zip", header: epubHeader, protectedResources: true }),
    (error) => error.code === "drm_or_encrypted",
  );
});
