"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.setup = setup;

var _getContext = require("../util/get-context");

var _getAllTemplates = require("../util/get-all-templates");

var _gatherAllTasks = require("./gather-all-tasks");

var _updateLockfiles = require("../lockfiles/update-lockfiles");

var _getTasksToRun = require("./get-tasks-to-run");

var _coatManifestTasks = require("../types/coat-manifest-tasks");

var _removeUnmanagedTasksFromLockfile = require("./remove-unmanaged-tasks-from-lockfile");

/**
 * Gathers and runs all tasks of a coat project.
 *
 * When running setup with the force = true option, all tasks will be
 * run regardless of whether they have been run before.
 *
 * @param cwd The working directory of the current coat project
 * @param force Whether to run tasks although they have been run before (e.g. when running the `coat setup` command directly)
 */
async function setup(cwd, force) {
  // Get context from cwd
  let context = await (0, _getContext.getContext)(cwd); // Gather all extended templates

  const allTemplates = (0, _getAllTemplates.getAllTemplates)(context);
  const allTasks = (0, _gatherAllTasks.gatherAllTasks)(allTemplates); // TODO: See #38
  // Let user interactively select which tasks should be run

  const tasksToRun = await (0, _getTasksToRun.getTasksToRun)(allTasks, context, force); // Run tasks sequentially to provide earlier task results
  // to following tasks

  for (const task of tasksToRun) {
    const taskResult = await task.run({
      context,
      previousResults: {
        global: context.coatGlobalLockfile.setup,
        local: context.coatLocalLockfile.setup
      }
    });
    const updateLockfileOptions = {
      context
    };
    const partialLockfileUpdate = {
      setup: {
        [task.id]: taskResult || {}
      }
    };

    switch (task.type) {
      case _coatManifestTasks.CoatTaskType.Global:
        updateLockfileOptions.updatedGlobalLockfile = partialLockfileUpdate;
        break;

      case _coatManifestTasks.CoatTaskType.Local:
        updateLockfileOptions.updatedLocalLockfile = partialLockfileUpdate;
        break;
    } // Update the lockfile in between task runs
    // to save task results in case a following task
    // throws an error


    context = await (0, _updateLockfiles.updateLockfiles)(updateLockfileOptions);
  } // Remove task results that are from tasks that are
  // no longer managed by coat


  context = await (0, _removeUnmanagedTasksFromLockfile.removeUnmanagedTasksFromLockfiles)(allTasks.filter(task => task.type === _coatManifestTasks.CoatTaskType.Global), allTasks.filter(task => task.type === _coatManifestTasks.CoatTaskType.Local), context);
  return context;
}