// Generated by CoffeeScript 2.3.2
(function() {
  // `cake` is a simplified version of [Make](http://www.gnu.org/software/make/)
  // ([Rake](http://rake.rubyforge.org/), [Jake](https://github.com/280north/jake))
  // for CoffeeScript. You define tasks with names and descriptions in a Cakefile,
  // and can call them from the command line, or invoke them from other tasks.

  // Running `cake` with no arguments will print out a list of all the tasks in the
  // current directory's Cakefile.

  // External dependencies.
  var CoffeeScript, cakefileDirectory, fatalError, fs, helpers, missingTask, oparse, options, optparse, path, printTasks, switches, tasks;

  fs = require('fs');

  path = require('path');

  helpers = require('./helpers');

  optparse = require('./optparse');

  CoffeeScript = require('./');

  // Register .coffee extension
  CoffeeScript.register();

  // Keep track of the list of defined tasks, the accepted options, and so on.
  tasks = {};

  options = {};

  switches = [];

  oparse = null;

  // Mixin the top-level Cake functions for Cakefiles to use directly.
  helpers.extend(global, {
    // Define a Cake task with a short name, an optional sentence description,
    // and the function to run as the action itself.
    task: function(name, description, action) {
      if (!action) {
        [action, description] = [description, action];
      }
      return tasks[name] = {name, description, action};
    },
    // Define an option that the Cakefile accepts. The parsed options hash,
    // containing all of the command-line options passed, will be made available
    // as the first argument to the action.
    option: function(letter, flag, description) {
      return switches.push([letter, flag, description]);
    },
    // Invoke another task in the current Cakefile.
    invoke: function(name) {
      if (!tasks[name]) {
        missingTask(name);
      }
      return tasks[name].action(options);
    }
  });

  // Run `cake`. Executes all of the tasks you pass, in order. Note that Node's
  // asynchrony may cause tasks to execute in a different order than you'd expect.
  // If no tasks are passed, print the help screen. Keep a reference to the
  // original directory name, when running Cake tasks from subdirectories.
  exports.run = function() {
    var arg, args, e, i, len, ref, results;
    global.__originalDirname = fs.realpathSync('.');
    process.chdir(cakefileDirectory(__originalDirname));
    args = process.argv.slice(2);
    CoffeeScript.run(fs.readFileSync('Cakefile').toString(), {
      filename: 'Cakefile'
    });
    oparse = new optparse.OptionParser(switches);
    if (!args.length) {
      return printTasks();
    }
    try {
      options = oparse.parse(args);
    } catch (error) {
      e = error;
      return fatalError(`${e}`);
    }
    ref = options.arguments;
    results = [];
    for (i = 0, len = ref.length; i < len; i++) {
      arg = ref[i];
      results.push(invoke(arg));
    }
    return results;
  };

  // Display the list of Cake tasks in a format similar to `rake -T`
  printTasks = function() {
    var cakefilePath, desc, name, relative, spaces, task;
    relative = path.relative || path.resolve;
    cakefilePath = path.join(relative(__originalDirname, process.cwd()), 'Cakefile');
    console.log(`${cakefilePath} defines the following tasks:\n`);
    for (name in tasks) {
      task = tasks[name];
      spaces = 20 - name.length;
      spaces = spaces > 0 ? Array(spaces + 1).join(' ') : '';
      desc = task.description ? `# ${task.description}` : '';
      console.log(`cake ${name}${spaces} ${desc}`);
    }
    if (switches.length) {
      return console.log(oparse.help());
    }
  };

  // Print an error and exit when attempting to use an invalid task/option.
  fatalError = function(message) {
    console.error(message + '\n');
    console.log('To see a list of all tasks/options, run "cake"');
    return process.exit(1);
  };

  missingTask = function(task) {
    return fatalError(`No such task: ${task}`);
  };

  // When `cake` is invoked, search in the current and all parent directories
  // to find the relevant Cakefile.
  cakefileDirectory = function(dir) {
    var parent;
    if (fs.existsSync(path.join(dir, 'Cakefile'))) {
      return dir;
    }
    parent = path.normalize(path.join(dir, '..'));
    if (parent !== dir) {
      return cakefileDirectory(parent);
    }
    throw new Error(`Cakefile not found in ${process.cwd()}`);
  };

}).call(this);
