"use strict";

var helpers = require('../helpers'),
    Request = require('../request'),
    printer = require('../printer'),
    fetch = require('node-fetch'),
    chalk = require('chalk'),
    Promise = require('es6-promise').Promise;

//TODO handle case sensitivity in yml keys
//TODO handle missing yml keys/values
//TODO pass in config as arg to exec from commmand?
class RequestCommand {

  constructor(program, config) {
      this._program = program;
      this._config = config;
      this._queue = [];
      this._stats = {
        totalRequests: 0,
        statusCodes: {},
      };
  }

  exec() {

      this._queue = this._createRequestQueue();

      this._executeRequests().then(() => {

          if (this._program.info) {
            console.log(chalk.white.underline('stats:'));
            console.log(JSON.stringify(this._stats, null, 4));
          }

      });
  }

  _createRequestQueue() {

      var env = this._config.envs[this._program.env || 'default'] || this._config.envs.default;

      return this._program.args.reduce((queue, curr) => {

          if (!this._config.requests[curr]) {
              console.log(`[info] request \"${curr}\" not found in requests.yml. Skipping.`);
              return queue;
          };

          queue.push(
            new Request(
              curr,
              this._config.requests[curr],
              { env: env, query: this._program.query })
          );

          return queue;

      }, []);
  }

  _executeRequests() {
      if  (this._program.async) {
          return this._executeRequestsAsync();
      } else {
          return this._executeRequestsSync();
      }
  }

  _executeRequestsSync() {

      return this._queue.reduce((sequence, request) => {

          return sequence.then(() => {

              request.start = process.hrtime();

              return fetch(request.url, request.config);

          }).then((resp) => {

              request.end = process.hrtime(request.start);

              return this._processResponse(request, resp);

          }).catch((e) => console.log(e));

      }, Promise.resolve());
  }

  _executeRequestsAsync() {

      var requestPromises = [];

      this._queue.reduce((requests, request) => {

        request.start = process.hrtime();

          var requestPromise = fetch(request.url, request.config)
              .then((resp) => {

                request.end = process.hrtime(request.start);

                  this._processResponse(request, resp);

              }).catch((e) => console.log(e));

          requestPromises.push(requestPromise);

      }, requestPromises);

      return Promise.all(requestPromises);
  }

  _processResponse(request, resp) {

      var retrieveMethod = resp.headers.get('content-type') === 'application/json' ?
          'json' :
          'text';

      return resp[retrieveMethod]().then((data) => {
          this._updateStats(resp.status, request.requestKey);
          printer.printRequestInfo(this._program, request, resp, data);
      });
  }

  _updateStats(status, request) {}
}

module.exports = RequestCommand;

@@ -12,16 +12,52 @@
 %22;%0A%0Avar 
+config = require('../config'), %0A    
 helpers 
@@ -449,16 +449,8 @@
 gram
-, config
 ) %7B%0A
@@ -496,129 +496,18 @@
 is._
-config = config;%0A      this._queue = %5B%5D;%0A      this._stats = %7B%0A        totalRequests: 0,%0A        statusCodes: %7B%7D,%0A      %7D
+queue = %5B%5D
 ;%0A  
@@ -842,22 +842,16 @@
 r env = 
-this._
 config.e
@@ -889,22 +889,16 @@
 lt'%5D %7C%7C 
-this._
 config.e
@@ -985,22 +985,16 @@
    if (!
-this._
 config.r
@@ -1227,22 +1227,16 @@
         
-this._
 config.r
@@ -2768,70 +2768,8 @@
 %3E %7B%0A
-          this._updateStats(resp.status, request.requestKey);%0A
     
@@ -2855,43 +2855,8 @@
  %7D%0A%0A
-  _updateStats(status, request) %7B%7D%0A
 %7D%0A%0Am

move config retrieval into request cmd