text: 'use strict';
  const assert = require('assert');
  const _ = require('lodash');
  
  /**
   * @module promptSuggestion
   * @description Utilities to allow remembering answers to Inquirer.js prompts
   */
  const promptSuggestion = module.exports;
  
  /**
   * Returns the default value for a checkbox
   *
   * @param  {Object} question Inquirer prompt item
   * @param  {*} defaultValue  The stored default value
   * @return {*}               Default value to set
   * @private
   */
  const getCheckboxDefault = (question, defaultValue) => {
    // For simplicity we uncheck all boxes and use .default to set the active ones
    for (const choice of question.choices) {
      if (typeof choice === 'object') {
        choice.checked = false;
      }
    }
  
    return defaultValue;
  };
  
  /**
   * Returns the default value for a list
   *
   * @param  {Object} question    Inquirer prompt item
   * @param  {*} defaultValue     The stored default value
   * @return {*}                  Default value to set
   * @private
   */
  const getListDefault = (question, defaultValue) => {
    const choiceValues = question.choices.map(
      choice => (typeof choice === 'object' ? choice.value : choice)
    );
    return choiceValues.indexOf(defaultValue);
  };
  
  /**
   * Return true if the answer should be store in
   * the global store, otherwise false
   *
   * @param  {Object}       question Inquirer prompt item
   * @param  {String|Array} answer   The inquirer answer
   * @param  {Boolean}      storeAll Should store default values
   * @return {Boolean}               Answer to be stored
   * @private
   */
  const storeListAnswer = (question, answer, storeAll) => {
    const choiceValues = question.choices.map(choice => {
      if (Object.prototype.hasOwnProperty.call(choice, 'value')) {
        return choice.value;
      }
  
      return choice;
    });
  
    const choiceIndex = choiceValues.indexOf(answer);
  
    // Check if answer is not equal to default value
    if (storeAll || question.default !== choiceIndex) {
      return true;
    }
  
    return false;
  };
  
  /**
   * Return true if the answer should be store in
   * the global store, otherwise false
   *
   * @param  {Object}       question Inquirer prompt item
   * @param  {String|Array} answer   The inquirer answer
   * @param  {Boolean}      storeAll Should store default values
   * @return {Boolean}               Answer to be stored
   * @private
   */
  const storeAnswer = (question, answer, storeAll) => {
    // Check if answer is not equal to default value or is undefined
    if (answer !== undefined && (storeAll || question.default !== answer)) {
      return true;
    }
  
    return false;
  };
  
  /**
   * Prefill the defaults with values from the global store
   *
   * @param  {Store}        store     `.yo-rc-global` global config
   * @param  {Array|Object} questions Original prompt questions
   * @return {Array}                  Prompt questions array with prefilled values.
   */
  promptSuggestion.prefillQuestions = (store, questions) => {
    assert(store, 'A store parameter is required');
    assert(questions, 'A questions parameter is required');
  
    const promptValues = store.get('promptValues') || {};
  
    if (!Array.isArray(questions)) {
      questions = [questions];
    }
  
    questions = questions.map(_.clone);
  
    // Write user defaults back to prompt
    return questions.map(question => {
      if (question.store !== true) {
        return question;
      }
  
      const storedValue = promptValues[question.name];
  
      if (storedValue === undefined || _.isFunction(question.choices)) {
        // Do not override prompt default when question.choices is a function,
        // since can't guarantee that the `storedValue` will even be in the returned choices
        return question;
      }
  
      // Override prompt default with the user's default
      switch (question.type) {
        case 'rawlist':
        case 'expand':
          question.default = getListDefault(question, storedValue);
          break;
        case 'checkbox':
          question.default = getCheckboxDefault(question, storedValue);
          break;
        default:
          question.default = storedValue;
          break;
      }
  
      return question;
    });
  };
  
  /**
   * Store the answers in the global store
   *
   * @param  {Store}        store     `.yo-rc-global` global config
   * @param  {Array|Object} questions Original prompt questions
   * @param  {Object}       answers   The inquirer answers
   * @param  {Boolean}      storeAll  Should store default values
   */
  promptSuggestion.storeAnswers = (store, questions, answers, storeAll) => {
    assert(store, 'A store parameter is required');
    assert(answers, 'A answers parameter is required');
    assert(questions, 'A questions parameter is required');
    assert.ok(_.isObject(answers), 'answers must be a object');
  
    storeAll = storeAll || false;
    const promptValues = store.get('promptValues') || {};
  
    if (!Array.isArray(questions)) {
      questions = [questions];
    }
  
    _.each(questions, question => {
      if (question.store !== true) {
        return;
      }
  
      let saveAnswer;
      const key = question.name;
      const answer = answers[key];
  
      switch (question.type) {
        case 'rawlist':
        case 'expand':
          saveAnswer = storeListAnswer(question, answer, storeAll);
          break;
  
        default:
          saveAnswer = storeAnswer(question, answer, storeAll);
          break;
      }
  
      if (saveAnswer) {
        promptValues[key] = answer;
      }
    });
  
    if (Object.keys(promptValues).length > 0) {
      store.set('promptValues', promptValues);
    }
  };
  