#!/usr/bin/env node

var path = require('path');
var chalk = require('chalk');
var prettyTime = require('pretty-hrtime');
var completion = require('../lib/utils/completion');
var taskTree = require('../lib/utils/task-tree');
var update = require('..');

var argv = require('minimist')(process.argv.slice(2));
update.extend('args', argv);

var stack = argv._;
var name = stack.shift();
var tasks = stack.length ? stack : ['default'];

var updater = update.updater(name);
var file = updater.module;

if (file) {
  var cwd = path.dirname(file);
  update.set('updater.cwd', cwd);
  update.emit('loaded');

  var instance = require(file);

  process.nextTick(function () {
    instance.start.apply(instance, tasks);
  }.bind(instance));
}

// exit with 0 or 1
var failed = false;
process.once('exit', function(code) {
  if (code === 0 && failed) {
    exit(1);
  }
});

update.on('last', function () {
  var args;
  if (argv.set) {
    args = argv.set.split('=');
    update.store.set.apply(update.store, args);
  }

  if (argv.has) {
    args = argv.has.split('=');
    update.store.has.apply(update.store, args);
  }

  if (argv.omit) {
    args = argv.omit.split('=');
    update.store.omit.apply(update.store, args);
  }

  if (argv.del) {
    update.store.delete({force: true});
  }
});

update.on('err', function () {
  failed = true;
});

update.on('task_start', function (e) {
  console.log('starting', '\'' + chalk.cyan(e.task) + '\'');
});

update.on('task_stop', function (e) {
  var time = prettyTime(e.hrDuration);
  console.log('finished', '\'' + chalk.cyan(e.task) + '\'', 'after', chalk.magenta(time));
});

update.on('task_err', function (e) {
  var msg = formatError(e);
  var time = prettyTime(e.hrDuration);
  console.log(chalk.cyan(e.task), chalk.red('errored after'), chalk.magenta(time));
  console.log(msg);
});

update.on('task_not_found', function (err) {
  console.log(chalk.red('task \'' + err.task + '\' is not in your updatefile'));
  console.log('please check the documentation for proper updatefile formatting');
  exit(1);
});

function logTasks(env, instance) {
  var tree = taskTree(instance.tasks);
  tree.label = 'Tasks for ' + tildify(instance.module);
  archy(tree).split('\n').forEach(function (v) {
    if (v.trim().length === 0) {
      return;
    }
    console.log(v);
  });
}

// format orchestrator errors
function formatError(e) {
  if (!e.err) {
    return e.message;
  }

  // PluginError
  if (typeof e.err.showStack === 'boolean') {
    return e.err.toString();
  }

  // normal error
  if (e.err.stack) {
    return e.err.stack;
  }

  // unknown (string, number, etc.)
  return new Error(String(e.err)).stack;
}


// fix stdout truncation on windows
function exit(code) {
  if (process.platform === 'win32' && process.stdout.bufferSize) {
    process.stdout.once('drain', function() {
      process.exit(code);
    });
    return;
  }
  process.exit(code);
}

if (!argv._.length) {
  update.emit('loaded');
}

@@ -305,37 +305,8 @@
 2));
-%0Aupdate.extend('args', argv);
 %0A%0Ava
@@ -398,16 +398,100 @@
 ult'%5D;%0A%0A
+var updater = typeof name !== 'undefined'%0A  ? update.updater(name)%0A  : exit(0);%0A%0A// 
 var upda
@@ -594,49 +594,168 @@
 e);%0A
+%0A
   
-update.set('updater.cwd', cwd);%0A  updat
+var instance = require(file);%0A  instance.set('updater.cwd', cwd);%0A  instance.set('updater.templates', cwd + '/templates');%0A  instance.emit('init');%0A  instanc
 e.em
@@ -768,31 +768,26 @@
 aded');%0A
-%0A
   
-var 
 instance
  = requi
@@ -778,31 +778,36 @@
 instance
- = require(file
+.extend('argv', argv
 );%0A%0A  pr

set variables after the instance