const { transferPlugin, checkPluginDependenies } = require("./transferPlugins");
const { transferSulu } = require("./transferSulu");
const fs = require("fs-extra");
const path = require("path");
const { tryReadFile } = require("./utils");

const manifestName = "buildManifest.json";

function tryReadManifest(src) {
  try {
    const manifest = fs.readJSONSync(path.join(src, manifestName)) || {};
    Object.values(manifest).forEach(
      (val) => (val.sourceModified = new Date(val.sourceModified))
    );
    return manifest;
  } catch (e) {
    return {};
  }
}

const coreLogic = ({
  incrementalBuild,
  buildOutputPath,
  version,
  log,
  suluDir,
  manifests,
  revision: _revision,
}) => {
  const buildManifest = incrementalBuild
    ? tryReadManifest(buildOutputPath)
    : {};
  if (
    !incrementalBuild &&
    fs.existsSync(path.join(buildOutputPath, manifestName))
  ) {
    console.log("removing");
    fs.writeFileSync(path.join(buildOutputPath, manifestName), "nonsense");
    fs.removeSync(path.join(buildOutputPath, manifestName));
  }
  const revision = _revision || new Date().toString();
  const dotenv = [];
  if (version) {
    dotenv.push(`VITE_BUILD_VERSION=${version}`);
  }
  manifests.forEach((manifest) => {
    checkPluginDependenies({
      manifest,
      buildOutputPath,
      log,
    });
  });

  transferSulu({
    log,
    sourcePath: suluDir,
    buildOutputPath,
    buildManifest,
    dotenv,
    revision,
  });

  manifests.forEach((manifest) => {
    transferPlugin({
      manifest,
      buildOutputPath,
      log,
      buildManifest,
      dotenv,
      revision,
    });
  });

  Object.entries(buildManifest).forEach(([fname, value]) => {
    if (!value.stillExists) {
      const toRemove = path.join(buildOutputPath, fname);
      console.log(
        "Source for built file no longer exists, removing built",
        toRemove
      );
      fs.removeSync(toRemove);
      delete buildManifest[fname];
    } else {
      // no longer needed, but object needs to be clean for save
      delete value.stillExists;
    }
  });

  fs.writeJSONSync(path.join(buildOutputPath, manifestName), buildManifest);

  const existingDotenv = tryReadFile(path.join(buildOutputPath, ".env"))
    .split("\n")
    .filter((x) => !!x);

  let mismatch = dotenv.length !== existingDotenv.length;
  dotenv.forEach((line, i) => {
    if (existingDotenv[i] !== line) {
      mismatch = true;
    }
  });

  if (mismatch) {
    log("Writing a new cumulated .env file");
    fs.writeFileSync(path.join(buildOutputPath, ".env"), dotenv.join("\n"));
  }

  // log(buildManifest);
};

module.exports = {
  coreLogic,
};
