text: /**
   * Container Generator
   */
  
  const fs = require('fs');
  const path = require('path');
  const componentExists = require('../utils/componentExists');
  
  function trimTemplateFile(template) {
    // Loads the template file and trims the whitespace and then returns the content as a string.
    return fs.readFileSync(path.join(__dirname, `./${template}`), 'utf8').replace(/\s*$/, '');
  }
  
  module.exports = {
    description: 'Add a container component',
    prompts: [{
      type: 'input',
      name: 'name',
      message: 'What should it be called?',
      default: 'Form',
      validate: (value) => {
        if ((/.+/).test(value)) {
          return componentExists(value) ? 'A component or container with this name already exists' : true;
        }
  
        return 'The name is required';
      },
    }, {
      type: 'list',
      name: 'component',
      message: 'Select a base component:',
      default: 'PureComponent',
      choices: () => ['PureComponent', 'Component'],
    }, {
      type: 'confirm',
      name: 'wantHeaders',
      default: false,
      message: 'Do you want headers?',
    }, {
      type: 'confirm',
      name: 'wantActionsAndReducer',
      default: true,
      message: 'Do you want an actions/constants/selectors/reducer tuple for this container?',
    }, {
      type: 'confirm',
      name: 'wantSagas',
      default: true,
      message: 'Do you want sagas for asynchronous flows? (e.g. fetching data)',
    }, {
      type: 'confirm',
      name: 'wantMessages',
      default: true,
      message: 'Do you want i18n messages (i.e. will this component use text)?',
    }, {
      type: 'confirm',
      name: 'wantRoutes',
      default: true,
      message: 'Do you want to add container routes?',
    }],
    actions: (data) => {
      // Generate index.js and index.test.js
      const actions = [{
        type: 'add',
        path: '../../app/containers/{{properCase name}}/index.js',
        templateFile: './container/index.js.hbs',
        abortOnFail: true,
      }, {
        type: 'add',
        path: '../../app/containers/{{properCase name}}/tests/index.test.js',
        templateFile: './container/test.js.hbs',
        abortOnFail: true,
      }];
  
      // If component wants messages
      if (data.wantMessages) {
        actions.push({
          type: 'add',
          path: '../../app/containers/{{properCase name}}/messages.js',
          templateFile: './container/messages.js.hbs',
          abortOnFail: true,
        });
      }
  
      // If they want actions and a reducer, generate actions.js, constants.js,
      // reducer.js and the corresponding tests for actions and the reducer
      if (data.wantActionsAndReducer) {
        // Actions
        actions.push({
          type: 'add',
          path: '../../app/containers/{{properCase name}}/actions.js',
          templateFile: './container/actions.js.hbs',
          abortOnFail: true,
        });
        actions.push({
          type: 'add',
          path: '../../app/containers/{{properCase name}}/tests/actions.test.js',
          templateFile: './container/actions.test.js.hbs',
          abortOnFail: true,
        });
  
        // Constants
        actions.push({
          type: 'add',
          path: '../../app/containers/{{properCase name}}/constants.js',
          templateFile: './container/constants.js.hbs',
          abortOnFail: true,
        });
  
        // Selectors
        actions.push({
          type: 'add',
          path: '../../app/containers/{{properCase name}}/selectors.js',
          templateFile: './container/selectors.js.hbs',
          abortOnFail: true,
        });
        actions.push({
          type: 'add',
          path: '../../app/containers/{{properCase name}}/tests/selectors.test.js',
          templateFile: './container/selectors.test.js.hbs',
          abortOnFail: true,
        });
  
        // Reducer
        actions.push({
          type: 'add',
          path: '../../app/containers/{{properCase name}}/reducer.js',
          templateFile: './container/reducer.js.hbs',
          abortOnFail: true,
        });
        actions.push({
          type: 'add',
          path: '../../app/containers/{{properCase name}}/tests/reducer.test.js',
          templateFile: './container/reducer.test.js.hbs',
          abortOnFail: true,
        });
      }
  
      // Sagas
      if (data.wantSagas) {
        actions.push({
          type: 'add',
          path: '../../app/containers/{{properCase name}}/sagas.js',
          templateFile: './container/sagas.js.hbs',
          abortOnFail: true,
        });
        actions.push({
          type: 'add',
          path: '../../app/containers/{{properCase name}}/tests/sagas.test.js',
          templateFile: './container/sagas.test.js.hbs',
          abortOnFail: true,
        });
      }
  
      // Sagas
      if (data.wantRoutes) {
        actions.push({
          type: 'add',
          path: '../../app/containers/{{properCase name}}/routes.js',
          templateFile: './container/routes.js.hbs',
          abortOnFail: true,
        });
  
        actions.push({
          type: 'modify',
          path: '../../app/routes.js',
          pattern: /(\/\/ import-module-end)/g,
          template: trimTemplateFile('importRoutes.hbs'),
        });
  
        actions.push({
          type: 'modify',
          path: '../../app/routes.js',
          pattern: /(\s{\n\s{0,}path: '\*',)/g,
          template: trimTemplateFile('injectRoutes.hbs'),
        });
      }
  
      return actions;
    },
  };
  