'use strict';

var arrayify = require('arrayify'),
    autoPlug = require('auto-plug'),
    glob = require('glob'),
    gulpUtil = require('gulp-util'),
    path = require('path');

function Plug(gulp, tasksDir, cwd) {
    tasksDir = tasksDir || '.gulpplug';
    cwd = cwd || path.dirname(module.parent.parent.filename);
    this.gulp = gulp;
    this.util = gulpUtil;
    this.cwd = cwd;
    this.tasksDir = path.join(this.cwd, tasksDir);
    this.taskGlob = '**/*.js';
    this.help = true;
    this.autoPlug = true;
    this.tasks = {};
    this.plugins = {};
}

Plug.prototype.getTasksFromGlob = function() {
    return glob.sync(this.taskGlob, {
        cwd: path.join(this.cwd, this.tasksDir)
    }).reduce(function(tasks, filepath) {
        tasks.push({
            file: filepath,
            name: this.getTasknameFromFilepath(filepath)
        });
        return tasks;
    }.bind(this), []);
};

Plug.prototype.addTasks = function(tasks) {
    tasks = tasks || this.getTasksFromGlob();
    arrayify(tasks).forEach(this.addTask.bind(this));
    return this;
};

Plug.prototype.addTask = function(task) {
    if (task.name === '' || this.tasks.hasOwnProperty(task.name)) {
        return this;
    }
    if (!task.hasOwnProperty('fn')) {
        task = this.requireTask(task);
    }
    if (typeof task.fn === 'function') {
        this.gulp.task(task.name, task.fn.bind(this));
        this.tasks[task.name] = task;
    }
    return this;
};

Plug.prototype.requireTask = function(task) {
    var taskModule = require(path.join(this.tasksDir, task.file));
    if (Array.isArray(taskModule) && taskModule.length === 2) {
        task.description = taskModule[0];
        task.fn = taskModule[1];
    } else {
        task.fn = taskModule;
    }
    return task;
};

Plug.prototype.getTasks = function() {
    return Object.keys(this.tasks).reduce(function(tasks, taskName) {
        tasks.push(this.tasks[taskName]);
        return tasks;
    }.bind(this), []);
};

Plug.prototype.addHelpTask = function() {
    this.addTask({
        name: 'help',
        fn: helpTask,
        description: 'display help message'
    });
    if (!this.gulp.hasTask('default')) {
        this.gulp.task('default', ['help']);
    }
    return this;
};

function helpTask(done) {
    var chalk = this.util.colors;
    this.util.log(chalk.yellow('=================================================='));
    this.util.log(chalk.yellow('Available Tasks:'));
    this.getTasks().forEach(function(task) {
        this.util.log(
            chalk.cyan(task.name) + chalk.gray(' ➜ ') +
            (task.description ? chalk.white(task.description) : chalk.gray('(no description)'))
        );
    }.bind(this));
    this.util.log(chalk.yellow('=================================================='));
    done();
}

Plug.prototype.getTasknameFromFilepath = function(filepath) {
    return filepath
        .replace(/([^a-z0-9_\.\/-]+)|(\.[^\.]+$)/gi, '')
        .replace(new RegExp(path.sep, 'g'), ':');
};

Plug.prototype.loadPlugins = function(autoPlugOptions) {
    autoPlugOptions = autoPlugOptions || {};
    if (!autoPlugOptions.hasOwnProperty('module')) {
        autoPlugOptions.module = module.parent.parent;
    }
    if (!autoPlugOptions.hasOwnProperty('config')) {
        autoPlugOptions.config = require(path.join(this.cwd, 'package.json'));
    }
    autoPlugOptions.prefix = 'gulp';
    this.plugins = autoPlug(autoPlugOptions);
    return this;
};

module.exports = Plug;

@@ -1360,16 +1360,35 @@
 sk.name,
+ task.dependencies,
  task.fn
@@ -1397,24 +1397,24 @@
 ind(this));%0A
-
         this
@@ -1533,16 +1533,30 @@
 odule = 
+arrayify(this.
 require(
@@ -1561,24 +1561,34 @@
 e(path.join(
+this.cwd, 
 this.tasksDi
@@ -1605,78 +1605,43 @@
 le))
+)
 ;%0A    
-if (Array.isArray(taskModule) && taskModule.length === 2) %7B%0A    
+task.fn = taskModule.pop();%0A
     
@@ -1673,28 +1673,39 @@
 dule
-%5B0%5D;%0A  
+.shift();%0A
     
-  
 task.
-fn
+dependencies
  = t
@@ -1717,61 +1717,51 @@
 dule
-%5B1%5D;%0A    %7D else %7B%0A        task.fn = taskModule;%0A    %7D
+.length %3E 0 ? arrayify(taskModule%5B0%5D) : %5B%5D;
 %0A   

allow a task module to export dependencies