"use strict";

var gulp = require("gulp");
var util = require("gulp-util");
var gulpif = require("gulp-if");
var rename = require("gulp-rename");
var notify = require("gulp-notify");

var buffer = require('vinyl-buffer');
var source = require("vinyl-source-stream");

var exorcist = require("exorcist");

var browserify = require("browserify");
var watchify = require("watchify");
var tsify = require("tsify");
var uglify = require("gulp-uglify");

var gutil = require("gulp-util");

var runSequence = require("run-sequence");

var lodash = require("lodash");

module.exports = function (options) {

    var vendorLibs = [
      "angular",
      "jquery",
      "jquery-shim",
      "lodash",
      "bootstrap-js",
      "angular-sanitize",
      "angular-ui-router",
      "angular-bootstrap-shim",
      "angular-translate",
      "angular-translate-loader-static-files",
      "angular-translate-shim",
      "numeral",
      "angular-numeraljs",
      "angular-numeraljs-shim",
      "leaflet",
      "angular-leaflet-directive",
      "angular-leaflet-directive-shim",
      "lodash"
    ];

    gulp.task("browserify:build:vendors", [], function () {
        var bundler = browserify({
            basedir: options.src, paths: [
              "../node_modules/",
              "../shims/"
            ]
        });

        lodash.forEach(vendorLibs, function (vendorLib) {
            bundler.require(vendorLib);
        });

        return bundler
          .bundle()
          .pipe(source("Vendor.js"))
          .pipe(buffer())
          .pipe(gulp.dest(options.build + "/scripts"))
          .pipe(uglify())
          .pipe(rename("Vendor.min.js"))
          .pipe(gulp.dest(options.build + "/scripts"));
    });

    var getBundler = function () {
        var bundler = browserify({ basedir: options.src, debug: true })
          .plugin(tsify, { target: "ES5", module: "commonjs" });

        lodash.forEach(vendorLibs, function (vendorLib) {
            bundler.external(vendorLib);
        });

        bundler.add("index.ts");

        return bundler;
    };

    var createAppBundle = function (aBundler) {
        return aBundler.bundle()
        .on("error", options.errorHandler("TypeScript"))
        .pipe(exorcist(options.build + "/scripts/Application.js.map"))
        .pipe(source("Application.js"))
        .pipe(buffer())
        .pipe(gulp.dest(options.build + "/scripts"))
        .pipe(uglify())
        .pipe(rename("Application.min.js"))
        .pipe(gulp.dest(options.build + "/scripts"));
    };

    gulp.task("browserify:build:application", function () {
        return createAppBundle(getBundler());
    });

    gulp.task("browserify:build", ["templates", "bower", "tsd:install"], function (callback) {
        runSequence(["browserify:build:vendors", "browserify:build:application"], callback);
    });

    gulp.task("browserify", ["browserify:build"], function () { });

    gulp.task("browserify:watch", [], function () {
        var bundler = getBundler();
        bundler = watchify(bundler);
        bundler.on("update", function () {
            util.log("Updating Application Bundle");
            createAppBundle(bundler).on('end', function () {
                util.log("Update Complete");
            });
        });

        return createAppBundle(bundler);
    });

    gulp.task("browserify:clean", function () {
    });
};
