import { spawnSync } from "node:child_process";
import { mkdirSync, readFileSync, writeFileSync } from "node:fs";

const packageByModule = {
  access: "@govoplan/access-webui",
  approvals: "@govoplan/approvals-webui",
  admin: "@govoplan/admin-webui",
  addresses: "@govoplan/addresses-webui",
  audit: "@govoplan/audit-webui",
  calendar: "@govoplan/calendar-webui",
  cases: "@govoplan/cases-webui",
  campaigns: "@govoplan/campaign-webui",
  committee: "@govoplan/committee-webui",
  dashboard: "@govoplan/dashboard-webui",
  dataflow: "@govoplan/dataflow-webui",
  datasources: "@govoplan/datasources-webui",
  dist_lists: "@govoplan/dist-lists-webui",
  docs: "@govoplan/docs-webui",
  files: "@govoplan/files-webui",
  forms: "@govoplan/forms-webui",
  forms_runtime: "@govoplan/forms-runtime-webui",
  idm: "@govoplan/idm-webui",
  mail: "@govoplan/mail-webui",
  notifications: "@govoplan/notifications-webui",
  organizations: "@govoplan/organizations-webui",
  ops: "@govoplan/ops-webui",
  policy: "@govoplan/policy-webui",
  portal: "@govoplan/portal-webui",
  postbox: "@govoplan/postbox-webui",
  projects: "@govoplan/projects-webui",
  reporting: "@govoplan/reporting-webui",
  risk_compliance: "@govoplan/risk-compliance-webui",
  scheduling: "@govoplan/scheduling-webui",
  search: "@govoplan/search-webui",
  tenancy: "@govoplan/tenancy-webui",
  views: "@govoplan/views-webui",
  voting: "@govoplan/voting-webui",
  workflow: "@govoplan/workflow-webui"
};

const cases = [
  { name: "core-only", modules: [] },
  { name: "access-only", modules: ["access"] },
  { name: "tenancy-only", modules: ["tenancy"] },
  { name: "access-with-tenancy", modules: ["access", "tenancy"] },
  { name: "admin-only", modules: ["admin"] },
  { name: "addresses-only", modules: ["addresses"] },
  { name: "access-with-admin", modules: ["access", "admin"] },
  { name: "admin-with-policy-and-audit", modules: ["access", "admin", "policy", "audit"] },
  { name: "dashboard-only", modules: ["dashboard"] },
  { name: "dataflow-only", modules: ["dataflow"] },
  { name: "datasources-only", modules: ["datasources"] },
  { name: "dataflow-with-datasources", modules: ["datasources", "dataflow"] },
  { name: "distribution-lists-only", modules: ["dist_lists"] },
  { name: "distribution-lists-with-providers", modules: ["addresses", "policy", "organizations", "idm", "dataflow", "dist_lists"] },
  { name: "workflow-only", modules: ["workflow"] },
  { name: "workflow-with-dataflow", modules: ["datasources", "dataflow", "workflow"] },
  { name: "views-only", modules: ["views"] },
  { name: "views-with-administration", modules: ["access", "admin", "views"] },
  { name: "calendar-only", modules: ["calendar"] },
  { name: "cases-only", modules: ["cases"] },
  { name: "committee-only", modules: ["committee"] },
  { name: "files-only", modules: ["files"] },
  { name: "forms-only", modules: ["forms"] },
  { name: "forms-runtime", modules: ["forms", "forms_runtime"] },
  { name: "mail-only", modules: ["mail"] },
  { name: "notifications-only", modules: ["notifications"] },
  { name: "organizations-only", modules: ["organizations"] },
  { name: "idm-with-organizations", modules: ["organizations", "idm"] },
  { name: "postbox-only", modules: ["postbox"] },
  { name: "portal-only", modules: ["portal"] },
  { name: "projects-only", modules: ["projects"] },
  { name: "reporting-only", modules: ["reporting"] },
  { name: "campaign-only", modules: ["campaigns"] },
  { name: "campaign-with-postbox", modules: ["campaigns", "postbox"] },
  { name: "campaign-with-files-no-mail", modules: ["campaigns", "files"] },
  { name: "campaign-with-mail-no-files", modules: ["campaigns", "mail"] },
  { name: "scheduling-only", modules: ["scheduling"] },
  { name: "scheduling-with-calendar", modules: ["scheduling", "calendar"] },
  { name: "search-only", modules: ["search"] },
  { name: "risk-compliance-only", modules: ["risk_compliance"] },
  { name: "docs-and-ops", modules: ["access", "docs", "ops"] },
  { name: "approvals-only", modules: ["access", "approvals"] },
  { name: "voting-only", modules: ["access", "voting"] },
  { name: "full-product", modules: ["access", "tenancy", "admin", "addresses", "approvals", "policy", "audit", "dashboard", "datasources", "dataflow", "dist_lists", "workflow", "views", "organizations", "idm", "cases", "committee", "campaigns", "files", "forms", "forms_runtime", "mail", "notifications", "docs", "ops", "calendar", "scheduling", "portal", "postbox", "projects", "reporting", "risk_compliance", "search", "voting"] }
];

const npmExec = process.env.npm_execpath;
const command = npmExec ? process.execPath : (process.platform === "win32" ? "npm.cmd" : "npm");
const baseArgs = npmExec ? [npmExec, "run", "build"] : ["run", "build"];
const collectedMetrics = [];

for (const testCase of cases) {
  const packages = testCase.modules.map((moduleId) => packageByModule[moduleId]).join(",");
  const env = {
    ...process.env,
    GOVOPLAN_WEBUI_MODULE_PACKAGES: packages,
    GOVOPLAN_WEBUI_BUILD_NAME: testCase.name
  };
  delete env.npm_config_tmp;
  delete env.NPM_CONFIG_TMP;
  if (process.env.GOVOPLAN_NPM_USERCONFIG) {
    env.NPM_CONFIG_USERCONFIG = process.env.GOVOPLAN_NPM_USERCONFIG;
    delete env.npm_config_userconfig;
  }
  console.log(`\n== WebUI module permutation: ${testCase.name} ==`);
  const result = spawnSync(command, baseArgs, {
    cwd: new URL("..", import.meta.url),
    env,
    stdio: "inherit"
  });
  if (result.status !== 0) {
    process.exit(result.status ?? 1);
  }
  collectedMetrics.push(
    JSON.parse(readFileSync(new URL("../dist/bundle-metrics.json", import.meta.url), "utf8"))
  );
}

const metricsDirectory = new URL("../dist/", import.meta.url);
mkdirSync(metricsDirectory, { recursive: true });
writeFileSync(
  new URL("module-permutation-bundle-metrics.json", metricsDirectory),
  `${JSON.stringify({ schemaVersion: 1, builds: collectedMetrics }, null, 2)}\n`
);
console.log(`\nRecorded bundle metrics for ${collectedMetrics.length} module permutations.`);
