'use strict';
var gutil = require('gulp-util');
var es = require('event-stream');
var fs = require('fs');
var q = require('q');
var spawn = require('./spawn');
var exec = require('./exec');
var log = require('./log');
var path = require('path');

var PLUGIN_NAME = 'gulp-dotcover';
var DEBUG = true;

var CWD = process.cwd();
function projectPathFor(path) {
  return [CWD, path].join('/');
}

function nugetRestore(options) {
  options = options || { }
  DEBUG = options.debug || false;
  options.force = options.force || false;
  if (DEBUG) {
      log.setThreshold(log.LogLevels.Debug);
  }
  var solutionFiles = [];
  
  var stream = es.through(function write(file) {
    if (!file) {
      fail(stream, 'file may not be empty or undefined');
    }
    solutionFiles.push(file);
    this.emit('data', file);
  }, function end() {
    runNugetRestoreWith(this, solutionFiles, options);
  }); 
  return stream;
};

function fail(stream, msg) {
	stream.emit('error', new gutil.PluginError(PLUGIN_NAME, msg));
}
function end(stream) {
	stream.emit('end');
}

function trim() {
	var args = Array.prototype.slice.call(arguments)
	var source = args[0];
	var replacements = args.slice(1).join(',');
	var regex = new RegExp("^[" + replacements + "]+|[" + replacements + "]+$", "g");
	return source.replace(regex, '');
}

function checkIfNugetIsAvailable(nugetPath, stream) {
    var finder = process.platform == 'win32' ? 'where' : 'which';
    return exec(finder, [nugetPath]);
}
 
function runNugetRestoreWith(stream, solutionFiles, options) {
    var ignored = 0;
    var solutions = solutionFiles.map(function(file) {
        return file.path.replace(/\\/g, '/');
    }).reduce(function(accumulator, item) {
        var solutionDir = path.dirname(item);
        accumulator.push(item);
        return accumulator;
    }, []);
    if (solutions.length === 0) {
        if (solutionFiles.length == 0) {
            return fail(stream, 'No solutions defined for nuget restore');
        }
    }
    var nuget = options.nuget || 'nuget.exe';
    checkIfNugetIsAvailable(nuget, stream).then(function() {
        var opts = {
            stdio: [process.stdin, process.stdout, process.stderr, 'pipe'],
            cwd: process.cwd()
        };

        var deferred = q.defer();
        var final = solutions.reduce(function(promise, item) {
            log.info('Restoring packages for: ' + item);
            var args = [ 'restore', item];
            return promise.then(function() {
                return spawn(nuget, args, opts).then(function() {
                    'Packages restored for: ' + item;
                });
            });
        }, deferred.promise);
        final.then(function() {
            end(stream);
        }).catch(function(err) {
            fail(stream, err);
        });

        deferred.resolve();
    }).catch(function() {
    log.error('Can\'t find nuget.exe. Either make sure it\'s in your path or explicitly provide a path in your nuget restore task options with the option "nuget"');
    fail(stream, 'Can\'t restore packages: no nuget )\':');
    });
}

module.exports = nugetRestore;

@@ -238,16 +238,46 @@
 'path');
+%0Avar which = require('which');
 %0A%0Avar PL
@@ -1400,105 +1400,477 @@
     
-var finder = process.platform == 'win32' ? 'where' : 'which';%0A    return exec(finder, %5BnugetPath%5D
+return new Promise(function(resolve, reject) %7B%0A        try %7B%0A            var nuget = which.sync('nuget');%0A            log.info('Using nuget.exe from: ' + nuget);%0A            resolve(nuget);%0A        %7D catch (ignore) %7B%0A            var message = 'Can%5C't find nuget.exe. Either make sure it%5C's in your path or explicitly provide a path in your nuget restore task options with the option %22nuget%22';%0A            log.error(message);%0A            reject(message);%0A        %7D%0A    %7D
 );%0A%7D
@@ -3248,234 +3248,39 @@
 ion(
-) %7B%0A    log.error('Can%5C't find nuget.exe. Either make sure it%5C's in your path or explicitly provide a path in your nuget restore task options with the option %22nuget%22');%0A    fail(stream, 'Can%5C't restore packages: no nuget )%5C':'
+err) %7B%0A        fail(stream, err
 );%0A 

convert from shell which/where to node package `which`