'use strict';

const inquirer = require('@serverless/utils/inquirer');
const { StepHistory } = require('@serverless/utils/telemetry');
const { resolveInitialContext } = require('./utils');

const steps = {
  service: require('./service'),
  dashboardLogin: require('./dashboard-login'),
  dashboardSetOrg: require('./dashboard-set-org'),
  awsCredentials: require('./aws-credentials'),
  deploy: require('./deploy'),
};

module.exports = async (context) => {
  const stepsDetails = new Map(
    Object.entries(steps).map(([stepName, step]) => {
      return [stepName, { configuredQuestions: step.configuredQuestions }];
    })
  );
  const { commandUsage } = context;
  const history = new Map();
  context = { ...context, inquirer, history };

  commandUsage.stepsHistory = history;
  commandUsage.stepsHistory.toJSON = () => {
    return Array.from(stepsDetails.entries()).map(([step, stepDetails]) => {
      const stepHistory = history.get(step);
      return {
        name: step,
        ...stepDetails,
        history: stepHistory ? stepHistory.toJSON() : [],
      };
    });
  };

  commandUsage.initialContext = resolveInitialContext(context);

  for (const [stepName, step] of Object.entries(steps)) {
    delete context.stepHistory;
    delete context.inapplicabilityReasonCode;
    const stepData = await step.isApplicable(context);
    Object.assign(stepsDetails.get(stepName), {
      isApplicable: Boolean(stepData),
      inapplicabilityReasonCode: context.inapplicabilityReasonCode,
      timestamp: Date.now(),
    });
    if (stepData) {
      process.stdout.write('\n');
      context.stepHistory = new StepHistory();
      context.history.set(stepName, context.stepHistory);
      await step.run(context, stepData);
    }
  }

  return {
    configuration: context.configuration,
  };
};
