#!/usr/bin/env node
const fs = require("fs");
const path = require("path");
const { execFileSync } = require("child_process");

const scriptDir = __dirname;
const repoRoot = path.resolve(scriptDir, "..");
const docsDir = path.join(repoRoot, "docs");
const homeDir = process.env.HOME || "";

function firstLine(text) {
  return (
    text
      .split(/\r?\n/)
      .map((line) => line.trim())
      .find(Boolean) || ""
  );
}

function findOne(root, matchArgs) {
  if (!root || !fs.existsSync(root)) {
    return "";
  }

  try {
    return firstLine(
      execFileSync("find", [root, ...matchArgs], {
        encoding: "utf8",
      }),
    );
  } catch {
    return "";
  }
}

function resolveMdToPdfPackage() {
  const explicit = process.env.MD_TO_PDF_PACKAGE;
  if (explicit && fs.existsSync(explicit)) {
    return explicit;
  }

  const found = findOne(path.join(homeDir, ".npm", "_npx"), [
    "-path",
    "*/node_modules/md-to-pdf",
    "-type",
    "d",
  ]);
  if (found) {
    return found;
  }

  throw new Error(
    "unable to find md-to-pdf package; set MD_TO_PDF_PACKAGE to a node_modules/md-to-pdf path",
  );
}

function resolveChromePath() {
  const envPaths = [
    process.env.MD_TO_PDF_CHROME,
    process.env.CHROME_HEADLESS_SHELL,
  ];

  for (const candidate of envPaths) {
    if (candidate && fs.existsSync(candidate)) {
      return candidate;
    }
  }

  return findOne(path.join(homeDir, ".cache", "puppeteer"), [
    "-path",
    "*/chrome-headless-shell",
    "-type",
    "f",
  ]);
}

function loadCssWithEmbeddedFont() {
  const cssPath = path.join(docsDir, "pdf.css");
  const fontPath = path.join(
    docsDir,
    "assets",
    "fonts",
    "NotoSansGlagolitic-Regular.ttf",
  );
  const fontBase64 = fs.readFileSync(fontPath).toString("base64");
  const css = fs.readFileSync(cssPath, "utf8");

  return css.replace(
    'url("assets/fonts/NotoSansGlagolitic-Regular.ttf")',
    `url("data:font/truetype;base64,${fontBase64}")`,
  );
}

async function main() {
  const mdToPdfPackage = resolveMdToPdfPackage();
  const { mdToPdf } = require(mdToPdfPackage);
  const chromePath = resolveChromePath();
  const baseOptions = {
    basedir: repoRoot,
    css: loadCssWithEmbeddedFont(),
    launch_options: {
      args: ["--no-sandbox", "--disable-setuid-sandbox"],
    },
    pdf_options: {
      format: "A4",
      printBackground: true,
      margin: {
        top: "18mm",
        right: "16mm",
        bottom: "18mm",
        left: "16mm",
      },
    },
  };

  if (chromePath) {
    baseOptions.launch_options.executablePath = chromePath;
  }

  const jobs = [
    {
      source: "docs/papers/SLOVO_WHITEPAPER.md",
      dest: "docs/papers/SLOVO_WHITEPAPER.pdf",
    },
    {
      source: "docs/language/MANIFEST.md",
      dest: "docs/papers/SLOVO_MANIFEST.pdf",
    },
    {
      source: "docs/papers/GLAGOL_WHITEPAPER.md",
      dest: "docs/papers/GLAGOL_WHITEPAPER.pdf",
    },
    {
      source: "docs/compiler/GLAGOL_COMPILER_MANIFEST.md",
      dest: "docs/papers/GLAGOL_COMPILER_MANIFEST.pdf",
    },
  ];

  for (const job of jobs) {
    const result = await mdToPdf(
      {
        path: path.join(repoRoot, job.source),
      },
      {
        ...baseOptions,
        dest: path.join(repoRoot, job.dest),
      },
    );
    if (!result) {
      throw new Error(`failed to render ${job.source}`);
    }
    console.log(job.dest);
  }
}

main().catch((error) => {
  console.error(error);
  process.exit(1);
});
