'use strict';

var combiner = require('stream-combiner2');
var gutil = require('gulp-util');
var uglify = require('gulp-uglify');
var streamify = require('gulp-streamify');
var rev = require('gulp-rev');
var rename = require('gulp-rename');
var buffer = require('gulp-buffer');
var concat = require('gulp-concat');
var source = require('vinyl-source-stream');
var streamqueue = require('streamqueue');
var browserify = require('browserify');
var watchify = require('watchify');
var babelify = require('babelify');
var envify = require('envify/custom');
var exorcist = require('exorcist');
var path = require('path');
var gulpIf = require('gulp-if');
var livereload = require('gulp-livereload');

var notify = require('./utils/notify');

module.exports = function buildJS(gulp, options) {
  gulp.task('js', function(cb) {
    var entryFile = './assets/js/client.es6.js';
    var buildjs = path.join(options.paths.build, options.paths.js);

    var shims = streamqueue({ objectMode: true });
    shims.queue(gulp.src('public/js/es5-shims.js'));
    shims.queue(gulp.src('node_modules/babel/browser-polyfill.js'));

    shims.done()
      .pipe(concat('shims.js'))
      .pipe(gulp.dest(buildjs));

    var bundler = browserify({
      cache: {},
      packageCache: {},
      fullPaths: true,
      debug: options.debug,
      extensions: ['.js', '.es6.js', '.jsx'],
      ignore: [
        'q',
        'moment',
      ],
    });

    if (options.watch) {
      bundler = watchify(bundler);
    }

    // Add in a few common dependencies so we don't end up browserifying
    // multiple versions in dev, because `npm link` behaves really oddly at
    // times
    bundler
      .require('moment')
      .require('q')
      .require('react')
      .require('dom-serializer')
      .require('reddit-text-js')
      .require('superagent');

    bundler.add(entryFile);

    bundler
      .transform(babelify.configure({
        ignore: /.+node_modules\/(moment|q|react|reddit-text-js|superagent|gsap|lodash)\/.+/i,
        extensions: ['.js', '.es6.js', '.jsx' ],
        sourceMap: !options.debug,
      }), {
        global: true,
      })
      .transform(envify({
        NODE_ENV: options.debug ? 'development' : 'production',
      }), {
        global: true,
      });

    var bundling = false;

    var rebundle = function() {
      if (bundling) {
        return;
      } else {
        bundling = true;
      }

      notify({
        message: 'Starting js...',
      });

      var stream = bundler.bundle();

      // combine streams for error handling
      var error = false;
      var combined = combiner.obj([
        stream,
        exorcist(buildjs + '/client.js.map'),
        source(entryFile),
        rename('client.js'),
        gulp.dest(buildjs),
        gulpIf(!options.debug, streamify(uglify())),
        rename('client.min.js'),
        gulp.dest(buildjs),
        buffer(),
        rev(),
        gulp.dest(buildjs),
        rev.manifest(),
        rename('client-manifest.json'),
        livereload(),
        gulp.dest(buildjs)
          .on('finish', function() {
            if (!error) {
              notify({
                message: 'Finished js',
              });
            }

            if (cb) { cb(); };
            cb = null;
            bundling = false;
            error = false;
          }),
      ]);

      // only catch errors in debug mode,
      // otherwise prod builds won't fail
      if (options.debug) {
        combined
          .on('error', function(e) {
            error = true;
            notify(e);
          });
      }
    }

    bundler.on('update', rebundle);
    return rebundle();
  });
};

@@ -2072,17 +2072,16 @@
 rceMap: 
-!
 options.

Fix sourcemaps