import buildTypes from "./buildTypes";
import buildGlobalHooks from "./buildGlobalHooks";
import prepare from "./prepare";
import generate from "./generate";
import cleanup from "./cleanup";
import validate from "./validate";
import provideConfig from "./provideConfig";
// @ts-ignore
import reportErrorToRollbar from "./rollbar.mjs";
import {
  checkNodeVersion,
  removeBuildSuccessFlag,
  storeBuildSuccessFlag,
} from "./utils";
import { initLogger, logError } from "./logger";

export default async () => {
  await initLogger("build");
  const breadcrumbs: string[] = [];

  try {
    const startTime = process.hrtime();
    checkNodeVersion();
    breadcrumbs.push("checkNodeVersion");
    removeBuildSuccessFlag();
    const config = await provideConfig();

    if (!config.plugins.length) {
      console.warn(
        "⚠️ No plugins found in your embeddable.config file. Example: https://github.com/embeddable-hq/vanilla-components/blob/main/embeddable.config.js#L5",
      );
      process.exit(0);
    }

    await validate(config);

    await prepare(config);

    await buildTypes(config);
    await buildGlobalHooks(config);

    for (const getPlugin of config.plugins) {
      const plugin = getPlugin();

      breadcrumbs.push(`${plugin.pluginName}: validate`);
      await plugin.validate(config);
      breadcrumbs.push(`${plugin.pluginName}: build`);
      await plugin.build(config);
      breadcrumbs.push(`${plugin.pluginName}: cleanup`);
      await plugin.cleanup(config);
    }

    // NOTE: likely this will be called inside the loop above if we decide to support clients with mixed frameworks simultaneously.
    breadcrumbs.push("generate");
    await generate(config, "sdk-react");
    // Calculating build time in seconds
    config.buildTime = process.hrtime(startTime);
    breadcrumbs.push("cleanup");
    await cleanup(config);
    await storeBuildSuccessFlag();
  } catch (error: any) {
    await logError({ command: "build", breadcrumbs, error });
    await reportErrorToRollbar(error);
    console.log(error);
    process.exit(1);
  }
};
