var gulp = require('gulp');
var parseArgs = require('minimist');
var fs = require('fs');

var TreeBuilder = require('./lib/tree-builder');
var HTMLWriter = require('./lib/html-writer');
var JSWriter = require('./lib/js-writer');
var StatsWriter = require('./lib/stats-writer');

var options = parseArgs(process.argv.slice(2));

function writeFile(output, data, cb) {
  fs.writeFile(output, data, function(err) {
    if (err)
      throw err;
    console.log('written results into \"' + output + '\".');
    cb();
  });
}

function readFile(filename, cb) {
  fs.readFile(filename, 'utf8', function(err, data) {
    if (err)
      throw err;
    var data = JSON.parse(data);
    cb(data);
  });
}

gulp.task('default', function() {
  console.log('Hello world!');
});

gulp.task('html', function(cb) {
  var name = options.file;

  readFile(name, function(data) {
    var writer = new HTMLWriter();
    var builder = new TreeBuilder(writer);
    builder.build(data);
    builder.write(writer);

    var output = 'result.html.html';
    writeFile(output, writer.getHTML(), cb);
  });
});

gulp.task('js', function(cb) {
  var name = options.file;

  readFile(name, function( data) {
    var writer = new JSWriter();
    var builder = new TreeBuilder(writer);
    builder.build(data);
    builder.write(writer);

    var output = 'result.js.html';
    writeFile(output, writer.getHTML(), cb);
  });

});

gulp.task('stats', function(cb) {
  var name = options.file;

  readFile(name, function(data) {
    var writer = new StatsWriter();
    var builder = new TreeBuilder(writer);
    builder.build(data);
    builder.write(writer);

    console.log(writer.getHTML());
    cb();
  });

});

@@ -693,95 +693,217 @@
 %0A%7D%0A%0A
-gulp.task('default', function() %7B
+/*%0A * Pipeline Stages%0A *%0A * Each stage accepts a data object and a callback, and is responsible for
 %0A 
+*
  c
-onsole.log('Hello world!');%0A%7D);%0A%0Agulp.task('html',
+alling the callback with the result of processing the data.%0A */%0A%0Afunction fileReader(filename) %7B%0A  return
  fun
@@ -912,58 +912,165 @@
 ion(
+_, 
 cb) %7B
-%0A  var name = options.file;%0A%0A  readFile(name,
+ readFile(filename, cb); %7D;%0A%7D%0A%0Afunction nullFilter() %7B%0A  return function(data, cb) %7B cb(data); %7D%0A%7D%0A%0Afunction treeBuilderWriter(WriterType) %7B%0A  return
  fun
@@ -1071,32 +1071,36 @@
 rn function(data
+, cb
 ) %7B%0A    var writ
@@ -1108,26 +1108,26 @@
 r = new 
-HTML
 Writer
+Type
 ();%0A    
@@ -1221,100 +1221,227 @@
 r);%0A
-%0A
     
-var output = 'result.html.html';%0A    writeFile(output, writer.getHTML(),
+cb(writer.getHTML());%0A  %7D%0A%7D;%0A%0Afunction fileOutput(filename) %7B%0A  return function(data, cb) %7B writeFile(filename, data, cb); %7D;%0A%7D%0A%0Afunction consoleOutput() %7B%0A  return function(data, cb) %7B console.log(data);
  cb
+(
 );
-%0A 
  %7D
-)
 ;%0A%7D
-);
 %0A%0Agu
@@ -1449,18 +1449,23 @@
 p.task('
-js
+default
 ', funct
@@ -1472,52 +1472,160 @@
 ion(
-cb
 ) %7B%0A  
-var name = options.file;%0A%0A  readFile
+console.log('Hello world!');%0A%7D);%0A%0A/*%0A * Constructing a pipeline%0A *%0A * Sorry for potato quality.%0A */%0Afunction buildTask(name, stages) %7B%0A  gulp.task
 (nam
@@ -1636,29 +1636,26 @@
 unction(
- data
+cb
 ) %7B%0A    
 var writ
@@ -1650,505 +1650,514 @@
     
-var writer = new JSWriter();%0A    var builder = new TreeBuilder(writer);%0A    builder.build(data);%0A    builder.write(writer
+for (var i = stages.length - 1; i %3E= 0; i--) %7B%0A      cb = (function(i, cb) %7B return function(data) %7B stages%5Bi%5D(data, cb); %7D %7D)(i, cb
 );%0A
-%0A
     
-var output = 'result.js.html';%0A    writeFile(output, writer.getHTML(), cb);%0A  %7D);%0A%0A%7D);%0A%0Agulp.task('stats', function(cb) %7B%0A  var name = options.file;%0A%0A  readFile(name, function(data) %7B%0A    var writer = new StatsWriter();%0A    var builder = new TreeBuilder(writer);%0A    builder.build(data);%0A    b
+%7D%0A    cb(null);%0A  %7D);%0A%7D;%0A%0A/*%0A * Some example pipelines.%0A */%0AbuildTask('html', %5BfileReader(options.file), treeBuilderWriter(HTMLWriter), fileOutput('result.html.html')%5D);%0AbuildTask('js', %5BfileReader(options.file), treeBuilderWriter(JSWriter), fileOutput('result.js.html')%5D);%0AbuildTask('stats', %5BfileReader(options.file), treeB
 uilder
-.w
+W
 rite
-(writer);%0A%0A    console.log(writer.getHTML());%0A    cb();%0A  %7D);%0A%0A%7D
+r(StatsWriter), consoleOutput()%5D
 );%0A

Refactor gulpfile into a pipeline.