'use strict';

var gulp = require('gulp')
  , sass = require('gulp-sass')
  , autoprefixer = require('gulp-autoprefixer')
  , imagemin = require('gulp-imagemin')
  , util = require('gulp-util')
  , browserify = require('browserify')
  , es2040 = require('es2040')
  , buffer = require('vinyl-buffer')
  , source = require('vinyl-source-stream')
  , uglify = require('gulp-uglify')
  , http_server = require('http-server')
  , connect_logger = require('connect-logger')
  , spawn = require('child_process').spawn
  ;

var SRC = {
  html:    './static/html',
  scss:    './static/scss',
  img:     './static/img',
  js:      './static/js',
  extra:   './static/rootExtra'
};

var DEST = {
  html:'./app/static',
  css: './app/static/css',
  img: './app/static/img',
  js:  './app/static/js'
};

gulp.task('html', function() {
  gulp.src(SRC.html + '/*.html')
    .pipe(gulp.dest(DEST.html));
});

gulp.task('html:watch', function() {
  gulp.watch(`${SRC.html}/*.html`, ['html']);
});

gulp.task('html:serve', function (cb) {
  var server = new http_server.HttpServer({
    root: 'app/static',
    before: [connect_logger()]
  });
  server.listen(8000, function () {
    util.log('HTTP server started on port 8000');
    cb();
  });
});

// Compile Sass into CSS
gulp.task('sass', function() {
  gulp.src(`${SRC.scss}/*.scss`)
    .pipe(sass({
      outputStyle: 'compressed'
    }).on('error', sass.logError))
    .pipe(autoprefixer('last 2 version'))
    .pipe(gulp.dest(DEST.css));
});

gulp.task('sass:watch', function() {
  gulp.watch(`${SRC.scss}/**/*.scss`, ['sass']);
});

// Copy/minify image assets
gulp.task('copy-images', function() {
  gulp.src(SRC.img + '/**/*.+(png|jpg|jpeg|gif|svg)')
    .pipe(imagemin())
    .pipe(gulp.dest(DEST.img));
});

gulp.task('copy-images:watch', function() {
  gulp.watch(SRC.img + '/**/*.+(png|jpg|jpeg|gif|svg)');
});

// Bundle and transpile javascript
gulp.task('scripts', function() {
  var b = browserify({
    entries: `${SRC.js}/main.js`,
    debug: true,
    transform: [es2040]
  });

  return b.bundle()
    .pipe(source('app.js'))
    .pipe(buffer())
    .pipe(gulp.dest(DEST.js));
});

gulp.task('build-scripts', function() {
  var b = browserify({
    entries: `${SRC.js}/main.js`,
    debug: false,
    transform: [es2040]
  });

  return b.bundle()
    .pipe(source('app.js'))
    .pipe(buffer())
    .pipe(uglify())
    .pipe(gulp.dest(DEST.js));
});

gulp.task('scripts:watch', function() {
  gulp.watch(`${SRC.js}/**/*.js`, ['scripts']);
});

gulp.task('extra', function() {
  gulp.src(SRC.extra + '/*.+(ico|xml|json)')
    .pipe(gulp.dest(DEST.html));
});

gulp.task('test', function(done) {
  const karmaArguments = ['start'];
  if (!process.argv.includes('--watch')) {
    karmaArguments.push('--single-run');
  }

  // Karma has a nice public API, but has issues where it can hang when trying to shut down after completing tests, so
  // run it as a separate process instead. See:
  // https://github.com/karma-runner/karma/issues/1693
  // https://github.com/karma-runner/karma/issues/1035
  const karma = spawn('./node_modules/.bin/karma', karmaArguments, {
    cwd: process.cwd(),
    stdio: 'inherit'
  });

  karma.on('close', code => {
    if (code) {
      done(new util.PluginError('Karma', `JS unit tests failed (code ${code})`));
      return
    }
    done();
  });
});

gulp.task('default', ['html', 'html:watch', 'html:serve', 'sass', 'sass:watch', 'copy-images', 'copy-images:watch', 'scripts', 'scripts:watch', 'extra']);
gulp.task('deploy', ['html', 'sass', 'build-scripts', 'extra', 'copy-images']);

@@ -2616,43 +2616,91 @@
 );%0A%0A
-gulp.task('test', function(done) %7B%0A
+function runKarmaTests (singleRun) %7B%0A  return new Promise((resolve, reject) =%3E %7B%0A  
   co
@@ -2735,51 +2735,31 @@
 '%5D;%0A
+  
   if (
-!process.argv.includes('--watch')
+singleRun
 ) %7B%0A
+  
     
@@ -2799,13 +2799,17 @@
 ');%0A
+  
   %7D%0A%0A
+  
   //
@@ -2875,16 +2875,23 @@
 ang when
+%0A    //
  trying 
@@ -2929,21 +2929,16 @@
 ests, so
-%0A  //
  run it 
@@ -2950,16 +2950,23 @@
 separate
+%0A    //
  process
@@ -2980,16 +2980,18 @@
 d. See:%0A
+  
   // htt
@@ -3037,16 +3037,18 @@
 es/1693%0A
+  
   // htt
@@ -3096,16 +3096,18 @@
 /1035%0A  
+ 
+ 
 const ka
@@ -3173,28 +3173,28 @@
     
+  
 cwd: 
-process.cwd(),%0A
+__dirname,%0A  
     
@@ -3210,16 +3210,18 @@
 nherit'%0A
+  
   %7D);%0A%0A 
@@ -3221,16 +3221,18 @@
  %7D);%0A%0A  
+ 
+ 
 karma.on
@@ -3251,24 +3251,26 @@
 de =%3E %7B%0A    
+  
 if (code) %7B%0A
@@ -3275,20 +3275,24 @@
 %7B%0A      
-done
+  reject
 (new uti
@@ -3365,15 +3365,20 @@
     
+  
 return
-%0A
+;%0A  
     
@@ -3387,19 +3387,169 @@
     
-don
+  resolv
 e();%0A  
+ 
-%7D
+ %7D);%0A  %7D);%0A%7D%0A%0Agulp.task('test', function() %7B%0A  return runKarmaTests(true);%0A%7D);%0A%0Agulp.task('test:watch', function() %7B%0A  return runKarmaTests(false
 );%0A%7D

Test task to watch, auto-run should be test:watch