// @ts-check

/**
 * Set `"scripts"` and `"config.startYear"` defaults on `package.json` if
 * missing
 */
function pkgSetup(pkg) {
  const { cliPkg } = require("../config");
  const existingScripts = pkg.get("scripts");
  const existingStartYear = pkg.get("config.startYear");
  const startYear = existingStartYear || new Date().getFullYear();

  pkg.set("scripts", {
    start: "npx acanto start",
    tpl: "npx acanto tpl",
    build: "npx acanto build",
    wipe: "npx acanto wipe",
    clean: "npx acanto clean",
    clear: "npx acanto clear",
    route: "npx acanto route",
    component: "npx acanto component",
    "core-sync": "npx acanto core-sync",
    help: "npx acanto help",
    test: "npx acanto test",
    link: "npx acanto link",
    "composer:refresh":
      "rm composer.lock && rm -r ./vendor/ && composer install",
    postinstall: "npx acanto core-sync",
    ...existingScripts,
  });
  pkg.set("config.startYear", startYear);
  pkg.save();
}

/**
 * Set browserlist configuration on `package.json`
 */
function pkgBrowserslistConfig(pkg, config) {
  const existingBrowserslist = pkg.get("browserslist");
  const browserslist = isCustomised(existingBrowserslist, config.browserList)
    ? existingBrowserslist
    : config.browserList;

  pkg.set("browserslist", browserslist);
  pkg.save();
}

/**
 * Set prettier configuration on `package.json`
 */
function pkgPrettierConfig(pkg, config) {
  const existingHusky = pkg.get("husky");
  const existingLintStaged = pkg.get("lint-staged");
  const existingOverrides = pkg.get("overrides");
  const husky = isCustomised(existingHusky, config.husky)
    ? existingHusky
    : config.husky;
  const overrides = isCustomised(existingOverrides, config.overrides)
    ? existingHusky
    : config.overrides;
  const lintStaged = isCustomised(existingLintStaged, config.lintStaged)
    ? existingLintStaged
    : config.lintStaged;

  pkg.set("husky", husky);
  pkg.set("overrides", overrides);
  pkg.set("lint-staged", lintStaged);
  pkg.save();
}

/**
 * Check if the existing configuration is different than the default,
 * so that we don't override it if it has been customised.
 */
function isCustomised(existing, _default) {
  if (!existing) {
    return false;
  }
  if (JSON.stringify(existing) === JSON.stringify(_default)) {
    return false;
  }
  return true;
}

/**
 * Collect subtasks in a single task that respect the gulp async lifecycle by
 * calling the callback on completion.
 */
module.exports = function pkg(callback) {
  const editJsonFile = require("edit-json-file");
  const paths = require("../paths");
  const pkg = editJsonFile(paths.pkg);
  const config = require("../config");

  pkgSetup(pkg);
  pkgBrowserslistConfig(pkg, config);
  pkgPrettierConfig(pkg, config);

  callback();
};
