import { defineConfig } from "vite";
import { cpSync, mkdirSync, readdirSync, rmSync } from "node:fs";
import { join } from "node:path";

const pdfjsAssets = () => ({
  name: "pdfjs-assets",
  closeBundle() {
    const outDir = "web/static/vendor/pdfjs";
    const srcDir =
      "node_modules/@bookhoard/foliate-js/vendor/pdfjs";
    mkdirSync(outDir, { recursive: true });
    cpSync(join(srcDir, "standard_fonts"), join(outDir, "standard_fonts"), {
      recursive: true,
    });
    cpSync(join(srcDir, "cmaps"), join(outDir, "cmaps"), { recursive: true });
  },
});

// emptyOutDir must stay false (web/static also holds tracked assets),
// so hashed chunks from previous builds would otherwise accumulate
// forever and leak into Docker images via the build context. Remove
// any *-<hash>.js(.map) that this build did not produce.
const cleanStaleChunks = () => {
  const produced = new Set<string>();
  return {
    name: "clean-stale-chunks",
    generateBundle(_options, bundle) {
      for (const fileName of Object.keys(bundle)) produced.add(fileName);
    },
    closeBundle() {
      const outDir = "web/static";
      const chunkRe = /-[A-Za-z0-9_-]{8}\.js(\.map)?$/;
      for (const f of readdirSync(outDir)) {
        if (chunkRe.test(f) && !produced.has(f)) {
          rmSync(join(outDir, f));
        }
      }
    },
  };
};

export default defineConfig({
  resolve: {
    alias: {
      "@": "/web/src",
      "foliate-js": "/node_modules/@bookhoard/foliate-js",
    },
  },
  base: "/static/",
  plugins: [pdfjsAssets(), cleanStaleChunks()],
  build: {
    outDir: "web/static",
    emptyOutDir: false,
    assetsDir: "",
    rollupOptions: {
      input: {
        main: "web/src/main.ts",
        reader: "web/src/reader/reader.ts",
      },
      output: {
        entryFileNames: "[name].js",
      },
    },
    target: "esnext",
    sourcemap: true,
    minify: "esbuild",
  },
});
