import fs from "fs-extra";
import path from "path";
import rushLib from "@microsoft/rush-lib";

const packageNames = rushLib.RushConfiguration.loadFromDefaultLocation({
  startingFolder: process.cwd(),
}).projects.map(({ packageName }) => packageName);

const safeImport = async (pathToFile) => {
  if (fs.existsSync(pathToFile)) {
    const metadata = await import(pathToFile);
    return metadata.default || metadata;
  }

  return null;
};

const getMetadata = async () => {
  const cwd = process.cwd();
  const getPackageDistPath = (packageName) => path.join(cwd, "./node_modules", packageName, "dist");

  const metaDataFiles = packageNames.flatMap((packageName) => {
    const metadataPath = path.join(getPackageDistPath(packageName));

    return [
      path.join(metadataPath, "metadata.js"),
      path.join(metadataPath, "components-metadata.js"),
    ];
  });

  const componentsMetadata = await Promise.all(metaDataFiles.map(safeImport));

  return componentsMetadata.flat().filter((metadata) => metadata !== null);
};

/**
 * Vite plugin to generate components-metadata.js
 *
 * @returns {import("vite").Plugin}
 */
export function generateComponentsMetadata() {
  return {
    name: "generate-components-metadata",
    apply: "build",
    async generateBundle() {
      const distDir = path.resolve(process.cwd(), "dist");
      const metadataPath = path.join(distDir, "components-metadata.js");

      // Ensure the dist directory exists
      fs.ensureDirSync(distDir);

      const metadataList = await getMetadata();

      const metadataContent = `module.exports = ${JSON.stringify(metadataList, null, 2)};`;
      fs.writeFileSync(metadataPath, metadataContent);
      console.log(`\nSuccessfully generated components metadata at ${metadataPath}\n`);
    },
  };
}
