/*jshint unused:true */
'use strict';

var exec = require('child_process').exec;

var $ = require('gulp-load-plugins')();
var eachAsync = require('each-async');
var gulp = require('gulp');
var mergeStream = require('merge-stream');
var readGlob = require('read-glob-promise');
var rimraf = require('rimraf');
var stylish = require('jshint-stylish');
var stringifyObject = require('stringify-object');

var bower = require('./bower.json');
var pkg = require('./package.json');

var parts = [
  '!function(A,B,C',
  '){A.GoogleAnalyticsObject=C;A[C]||(A[C]=function(){\\n' +
  '(A[C].q=A[C].q||[]).push(arguments)});A[C].l=+new Date',
  '=B.createElement(',
  '"//www.google-analytics.com/analytics.js"',
  '.parentNode.insertBefore(',
  '=B.getElementsByTagName(D)[0];',
  '(window,document,"ga"'
];

var productionDir = 'snippets-production';
var casperjsPath = 'node_modules/.bin/casperjs';
if (process.platform === 'win32') {
  casperjsPath += '.exe';
}

gulp.task('lint', function() {
  gulp.src(['{,test/*/}*.js', '!template.js'])
    .pipe($.jshint())
    .pipe($.jshint.reporter(stylish))
    .pipe($.jshint.reporter('fail'))
    .pipe($.jscs('package.json'));
  gulp.src('*.json')
    .pipe($.jsonlint())
    .pipe($.jsonlint.reporter());
});

gulp.task('clean:minify', rimraf.bind(null, productionDir));

gulp.task('minify', ['clean:minify'], function() {
  return gulp.src('*.js', {cwd: 'snippets-development'})
    .pipe($.uglify({
      mangle: false,
      compress: {sequences: false}
    }))
    .pipe($.replace(/\(\){|Element\(.+?\).|js";|\(F,G\)}/g, '$&\n'))
    .pipe($.rename({suffix: '-production'}))
    .pipe($.size({showFiles: true}))
    .pipe(gulp.dest(productionDir));
});

gulp.task('clean:dist', rimraf.bind(null, 'scripts'));

gulp.task('build', ['lint', 'clean:dist', 'minify'], function(cb) {
  readGlob(productionDir + '/*.js', 'utf8').then(function(contents) {
    var snippets = contents.map(function(content) {
      content = parts.reduce(function(result, part, idx) {
        return result.replace(part.replace(/\\n/g, '\n'), '\' + parts[' + idx + '] + \'');
      }, content).replace(/\n/g, '\\n');

      return ('\'' + content + '\'').replace(/(^'|'') \+ /g, '');
    });

    var partsStringified = stringifyObject(parts, {indent: '  '});

    var commonJs = gulp.src('template.js')
      .pipe($.template({
        parts: partsStringified,
        snippets: snippets,
        wrap: false
      }))
      .pipe($.rename(pkg.main))
      .pipe($.jscs({maximumLineLength: 170}))
      .pipe(gulp.dest(''));

    var browser = gulp.src('template.js')
      .pipe($.template({
        parts: partsStringified,
        snippets: snippets,
        wrap: true
      }))
      .pipe($.rename(bower.main))
      .pipe($.jscs({maximumLineLength: 170}))
      .pipe(gulp.dest(''));

    mergeStream(commonJs, browser).on('end', cb);
  }, cb);
});

gulp.task('test', ['build'], function(cb) {
  eachAsync([
    'node test/test-api/test',
    casperjsPath + ' test test/test-browser/run-casper.js'
  ], function(cmd, index, next) {
    exec(cmd, function(err, stderr, stdout) {
      process.stdout.write(stderr);
      process.stderr.write(stdout);
      next(err);
    });
  }, cb);
});

gulp.task('watch', function() {
  gulp.watch('{,src/}*.js', ['test']);
  gulp.watch('{*.json,.jshintrc}', ['lint']);
});

gulp.task('default', ['test', 'watch']);

@@ -965,16 +965,24 @@
 sk('lint
+:scripts
 ', funct
@@ -987,24 +987,31 @@
 ction() %7B%0A  
+return 
 gulp.src(%5B'%7B
@@ -1043,16 +1043,50 @@
 e.js'%5D)%0A
+    .pipe($.jscs(pkg.jscsConfig))%0A
     .pip
@@ -1177,45 +1177,59 @@
 l'))
-%0A    .pipe($.jscs('package.json'));%0A 
+;%0A%7D);%0A%0Agulp.task('lint:json', function() %7B%0A  return
  gul
@@ -1390,16 +1390,45 @@
 nify', %5B
+'lint:scripts', 'lint:json', 
 'clean:m
@@ -1680,16 +1680,53 @@
 rename(%7B
+%0A      dirname: productionDir,%0A      
 suffix: 
@@ -1738,16 +1738,21 @@
 duction'
+%0A    
 %7D))%0A    
@@ -1804,29 +1804,18 @@
 lp.dest(
-productionDir
+''
 ));%0A%7D);%0A
@@ -1895,16 +1895,8 @@
 ', %5B
-'lint', 
 'cle
@@ -2582,81 +2582,8 @@
 in))
-%0A      .pipe($.jscs(%7BmaximumLineLength: 170%7D))%0A      .pipe(gulp.dest(''))
 ;%0A%0A 
@@ -2771,16 +2771,53 @@
 r.main))
+;%0A%0A    mergeStream(commonJs, browser)
 %0A      .
@@ -2885,45 +2885,15 @@
 ''))
-;%0A
 %0A
+ 
     
-mergeStream(commonJs, browser)
+ 
 .on(
@@ -2901,32 +2901,42 @@
 end', cb);%0A  %7D, 
+cb).catch(
 cb);%0A%7D);%0A%0Agulp.t

update gulp tasks