const fs = require("fs-extra");
const path = require("path");
const { tryReadFile } = require("./utils");

function transferSulu({
  sourcePath,
  buildOutputPath,
  log,
  buildManifest,
  dotenv = [],
  revision = 0,
}) {
  log(`Transferring sulu from: ${sourcePath} to: ${buildOutputPath}`);

  if (!fs.existsSync(path.join(sourcePath, "package.json"))) {
    throw new Error(
      `Base path of ${sourcePath} does not contain a package.json, aborting.`
    );
  }

  // by now the output directory is considered existing and prepared.
  fs.copySync(sourcePath, buildOutputPath, {
    recursive: true,
    dereference: true,
    filter: (src) => {
      // directory check
      // do not let anything in node_modules, .git
      if (["node_modules", ".git"].find((p) => src.includes(p))) {
        return false;
      }

      const { mtime } = fs.lstatSync(src);
      const fnameRel = src.replace(sourcePath, "");

      // as directory is walked one file at a time, let directories through always.
      if (fs.lstatSync(src).isDirectory()) {
        return true;
      }

      // file itself check
      // do not if: is .env (handled afterwards)
      const c1 = src.includes(".env");
      // do not if: is yarn.lock, -p is set, yarn.lock exists in dest
      // const c2 = src.includes("yarn.lock") && incrementalBuild && fs.existsSync(path.join(buildOutputPath, "yarn.lock"));
      // if either:
      // - not in manifest
      // - and:
      //   - in manifest
      //   - came from the same plugin
      //   - timestamp newer than what it was when the file was created
      const manifest = buildManifest[fnameRel];
      const c3 =
        !manifest ||
        (manifest.by == "sulu" &&
          manifest.sourceModified.valueOf() < new Date(mtime).valueOf());

      const shouldCopy = !c1 && c3;

      if (shouldCopy) {
        buildManifest[fnameRel] = {
          by: "sulu",
          sourceModified: new Date(mtime),
          revision,
        };
      }
      if (buildManifest[fnameRel]) {
        buildManifest[fnameRel].stillExists = true;
      }
      return shouldCopy;
    },
  });

  dotenv.push(
    ...tryReadFile(path.join(sourcePath, ".env"))
      .split("\n")
      .filter((x) => !!x)
  );

  return {
    buildManifest,
    dotenv,
  };
}

module.exports = {
  transferSulu,
};
