'use strict';
var _ = require('lodash');
var errors = require('./helpers/errors');
var variables = require('./helpers/variables');
var emitter = require('./emitter');
var shell = require('shelljs');
var sequest = require('sequest');

// Public
module.exports = function exec(taskname, vars) {
  errors.checkString(taskname, 'taskname must be a string');
  errors.checkNonEmpty(taskname, 'taskname must be non-empty');

  var task = getTask(taskname);
  if (!(_.isUndefined(vars))) {
    task = variables.processVars(task, vars);
  }

  execTask(task, taskResponse);
}


// Private
function getTask(taskname) {
  var task = global.taskList[taskname];
  errors.checkDefined(task, taskname + ' is not defined');

  return task;
}

function execTask(task, callback) {
  if (task.remote == 'localhost') {
    localTask(task, callback);
  } else {
    remoteTask(task, callback);
  }
}

function localTask(task, callback) {
  var commands = task.commands;

  try {
    var result = shell.exec('cd ' + task.cwd);
    if (result.code != 0) {
      return callback(result.output);
    }
  } catch(err) {
    return callback(err);
  }

  for (var i = 0; i < commands.length; i++) {
    try {
      var result = shell.exec(commands[i]);
      if (result.code != 0) {
        return callback(result.output);
      }
      emitter.emit('command', commands[i]);
    } catch(err) {
      return callback(err);
    }
  }

  return callback(null, task);
}

function remoteTask(task, callback) {
  var commands = task.commands;

  try {
    var seq = sequest(task.remote);
    seq.write('echo Opening connection');
  } catch(err) {
    return callback(err);
  }

  for (var i = 0; i < commands.length; i++) {
    try {
      seq.write("cd " + task.cwd + " && " + commands[i]);
      emitter.emit('command', commands[i]);
    } catch(err) {
      return callback(err);
    }
  }

  try {
    seq.write('echo Closing connection', function(){
      seq.end();
      return callback(null, task);
    });
  } catch(err) {
    return callback(err);
  }
}

function taskResponse(err, task) {
  if (err){
    throw new Error(err);
  }
  emitter.emit('end');
}

@@ -915,41 +915,8 @@
 ) %7B%0A
-  var commands = task.commands;%0A%0A
   tr
@@ -1092,48 +1092,47 @@
 %0A%0A  
-for (var i = 0; i %3C commands.length; i++
+task.commands.forEach(function (command
 ) %7B%0A
@@ -1174,28 +1174,24 @@
 exec(command
-s%5Bi%5D
 );%0A      if 
@@ -1288,36 +1288,32 @@
 ommand', command
-s%5Bi%5D
 );%0A    %7D catch(e
@@ -1351,24 +1351,26 @@
 );%0A    %7D%0A  %7D
+);
 %0A%0A  return c
@@ -1435,41 +1435,8 @@
 ) %7B%0A
-  var commands = task.commands;%0A%0A
   tr
@@ -1479,50 +1479,8 @@
 e);%0A
-    seq.write('echo Opening connection');%0A
   %7D 
@@ -1529,48 +1529,47 @@
 %0A%0A  
-for (var i = 0; i %3C commands.length; i++
+task.commands.forEach(function (command
 ) %7B%0A
@@ -1625,31 +1625,41 @@
  %22 + command
-s%5Bi%5D);%0A
+, function() %7B%0A  
       emitte
@@ -1687,12 +1687,18 @@
 mand
-s%5Bi%5D
+);%0A      %7D
 );%0A 
@@ -1748,24 +1748,26 @@
 );%0A    %7D%0A  %7D
+);
 %0A%0A  try %7B%0A  
@@ -1788,9 +1788,9 @@
 cho 
-C
+c
 losi
@@ -1802,16 +1802,19 @@
 nnection
+...
 ', funct
@@ -1818,16 +1818,17 @@
 nction()
+ 
 %7B%0A      

Use forEach instead of for loops, fixes #8