text: 'use strict';
  
  const BbPromise = require('bluebird');
  const _ = require('lodash');
  
  class Invoke {
    constructor(serverless, options) {
      this.serverless = serverless;
      this.options = options || {};
  
      this.commands = {
        invoke: {
          usage: 'Invoke a deployed function',
          configDependent: true,
          lifecycleEvents: ['invoke'],
          options: {
            function: {
              usage: 'The function name',
              required: true,
              shortcut: 'f',
            },
            stage: {
              usage: 'Stage of the service',
              shortcut: 's',
            },
            region: {
              usage: 'Region of the service',
              shortcut: 'r',
            },
            qualifier: {
              usage: 'Version number or alias to invoke',
              shortcut: 'q',
            },
            path: {
              usage: 'Path to JSON or YAML file holding input data',
              shortcut: 'p',
            },
            type: {
              usage: 'Type of invocation',
              shortcut: 't',
            },
            log: {
              usage: 'Trigger logging data output',
              shortcut: 'l',
            },
            data: {
              usage: 'Input data',
              shortcut: 'd',
            },
            raw: {
              usage: 'Flag to pass input data as a raw string',
            },
          },
          commands: {
            local: {
              usage: 'Invoke function locally',
              lifecycleEvents: ['loadEnvVars', 'invoke'],
              options: {
                'function': {
                  usage: 'Name of the function',
                  shortcut: 'f',
                  required: true,
                },
                'path': {
                  usage: 'Path to JSON or YAML file holding input data',
                  shortcut: 'p',
                },
                'data': {
                  usage: 'input data',
                  shortcut: 'd',
                },
                'raw': {
                  usage: 'Flag to pass input data as a raw string',
                },
                'context': {
                  usage: 'Context of the service',
                  shortcut: 'c',
                },
                'contextPath': {
                  usage: 'Path to JSON or YAML file holding context data',
                  shortcut: 'x',
                },
                'env': {
                  usage: 'Override environment variables. e.g. --env VAR1=val1 --env VAR2=val2',
                  shortcut: 'e',
                },
                'docker': { usage: 'Flag to turn on docker use for node/python/ruby/java' },
                'docker-arg': {
                  usage: 'Arguments to docker run command. e.g. --docker-arg "-p 9229:9229"',
                },
              },
            },
          },
        },
      };
  
      this.hooks = {
        'invoke:local:loadEnvVars': () => BbPromise.bind(this).then(this.loadEnvVarsForLocal),
        'after:invoke:invoke': () => BbPromise.bind(this).then(this.trackInvoke),
        'after:invoke:local:invoke': () => BbPromise.bind(this).then(this.trackInvokeLocal),
      };
    }
  
    trackInvoke() {
      return BbPromise.resolve();
    }
  
    trackInvokeLocal() {
      return BbPromise.resolve();
    }
  
    /**
     * Set environment variables for "invoke local" that are provider independent.
     */
    loadEnvVarsForLocal() {
      const defaultEnvVars = {
        IS_LOCAL: 'true',
      };
  
      _.merge(process.env, defaultEnvVars);
  
      // Turn zero or more --env options into an array
      //   ...then split --env NAME=value and put into process.env.
      [].concat(this.options.env || []).forEach(itm => {
        const splitItm = itm.split('=');
        process.env[splitItm[0]] = splitItm[1] || '';
      });
  
      return BbPromise.resolve();
    }
  }
  
  module.exports = Invoke;
  