import { defineConfig } from "rollup";
import nodeResolve from "@rollup/plugin-node-resolve";
import sucrase from "@rollup/plugin-sucrase";
import terser from "@rollup/plugin-terser";
import { createHash } from "node:crypto";
import license from "rollup-plugin-license";
import { readFileSync } from "node:fs";
import prettier from "prettier";

const pkg = JSON.parse(readFileSync("./package.json"));

const LICENSE_BANNER =
  "SPDX-License-Identifier: Unlicense\n" +
  "This file was automatically generated by https://github.com/yt-dlp/ejs" +
  "<% if (dependencies && dependencies.length) { %>" +
  "\n\nBundled Dependencies:" +
  "<% _.forEach(dependencies, function (dependency) { if (!dependency.private) { %>" +
  "\n\n---\nName: <%= dependency.name %>" +
  "<% if (dependency.version) { %>\nVersion: <%= dependency.version %><% } %>" +
  "\nLicense: <%= dependency.license %>" +
  "<% if (dependency.repository && dependency.repository.url) { %>\nRepository: <%= dependency.repository.url %><% } %>" +
  "<% if (dependency.homepage && dependency.homepage.url) { %>\nHomepage:  <%= dependency.homepage.url %><% } %>" +
  "<% if (dependency.author) { %>\nAuthor: <%= dependency.author.text() %><% } %>" +
  "<% if (dependency.licenseText) { %>\n\n<%= dependency.licenseText %><% } %>" +
  "\n---<% } }) %>\n<% } %>";

function printHash() {
  return {
    name: "hash-output-plugin",
    writeBundle(_options, bundle) {
      for (const [fileName, assetInfo] of Object.entries(bundle)) {
        if (assetInfo.code) {
          try {
            const digest = createHash("sha3-512")
              .update(assetInfo.code)
              .digest("hex");
            console.log(`SHA3-512 for ${assetInfo.fileName}: ${digest}`);
          } catch (err) {
            console.error(`Error hashing ${fileName}:`, err.message);
          }
        }
      }
    },
  };
}

function dynamicImportRewrite({ format = "deno" } = {}) {
  return {
    name: "dynamic-import-rewrite-plugin",
    resolveId(source) {
      if (pkg.dependencies[source]) {
        if (format === "deno") {
          return {
            id: `npm:${source}@${pkg.dependencies[source]}`,
            external: true,
          };
        } else if (format === "bun") {
          return {
            id: `${source}@${pkg.dependencies[source]}`,
            external: true,
          };
        }
        return null;
      }
      return null;
    },
    renderDynamicImport() {
      return null;
    },
  };
}

function prettifyOutput() {
  return {
    name: "prettify-output",
    renderChunk(code) {
      return prettier.format(code, { parser: "babel", singleQuote: true });
    },
  };
}

export default defineConfig([
  {
    input: "src/yt/solver/main.ts",
    output: {
      name: "jsc",
      globals: {
        astring: "astring",
        input: "input",
        meriyah: "meriyah",
      },
      file: "dist/yt.solver.core.js",
      format: "iife",
    },
    external: ["astring", "meriyah"],
    plugins: [
      nodeResolve(),
      sucrase({
        exclude: ["node_modules/**"],
        transforms: ["typescript"],
      }),
      license({
        banner: {
          commentStyle: "ignored",
          content: LICENSE_BANNER,
        },
      }),
      // Use terser to remove comments but do not minify
      terser({
        compress: false,
        mangle: false,
      }),
      prettifyOutput(),
      printHash(),
    ],
  },
  {
    input: "src/yt/solver/main.ts",
    output: {
      name: "jsc",
      globals: {
        astring: "astring",
        input: "input",
        meriyah: "meriyah",
      },
      file: "dist/yt.solver.core.min.js",
      compact: true,
      format: "iife",
      minifyInternalExports: true,
    },
    external: ["astring", "meriyah"],
    plugins: [
      nodeResolve(),
      sucrase({
        exclude: ["node_modules/**"],
        transforms: ["typescript"],
      }),
      license({
        banner: {
          commentStyle: "ignored",
          content: LICENSE_BANNER,
        },
      }),
      terser(),
      printHash(),
    ],
  },
  {
    input: "src/yt/solver/lib.ts",
    output: {
      name: "lib",
      file: "dist/yt.solver.lib.js",
      format: "iife",
      exports: "named",
    },
    plugins: [
      nodeResolve(),
      sucrase({
        exclude: ["node_modules/**"],
        transforms: ["typescript"],
      }),
      license({
        banner: {
          commentStyle: "ignored",
          content: LICENSE_BANNER,
        },
      }),
      // Use terser to remove comments but do not minify
      terser({
        compress: false,
        mangle: false,
      }),
      prettifyOutput(),
      printHash(),
    ],
  },
  {
    input: "src/yt/solver/lib.ts",
    output: {
      name: "lib",
      file: "dist/yt.solver.lib.min.js",
      compact: true,
      format: "iife",
      minifyInternalExports: true,
    },
    plugins: [
      nodeResolve(),
      sucrase({
        exclude: ["node_modules/**"],
        transforms: ["typescript"],
      }),
      license({
        banner: {
          commentStyle: "ignored",
          content: LICENSE_BANNER,
        },
      }),
      terser(),
      printHash(),
    ],
  },
  {
    input: "src/yt/solver/dynamic.lib.ts",
    output: {
      name: "lib",
      file: "dist/yt.solver.deno.lib.js",
      format: "es",
    },
    plugins: [
      dynamicImportRewrite(),
      license({
        banner: {
          commentStyle: "ignored",
          content: LICENSE_BANNER,
        },
      }),
      // Use terser to remove comments but do not minify
      terser({
        compress: false,
        mangle: false,
      }),
      prettifyOutput(),
      printHash(),
    ],
  },
  {
    input: "src/yt/solver/dynamic.lib.ts",
    output: {
      name: "lib",
      file: "dist/yt.solver.bun.lib.js",
      format: "es",
    },
    plugins: [
      dynamicImportRewrite({ format: "bun" }),
      license({
        banner: {
          commentStyle: "ignored",
          content: LICENSE_BANNER,
        },
      }),
      // Use terser to remove comments but do not minify
      terser({
        compress: false,
        mangle: false,
      }),
      prettifyOutput(),
      printHash(),
    ],
  },
]);
