var gulp = require('gulp');
var babel = require('gulp-babel');
var jshint = require('gulp-jshint');
var nodemon = require('gulp-nodemon');
var uglify = require('gulp-uglify');
var util = require('gulp-util');
var mocha = require('gulp-mocha');
var todo = require('gulp-todo');
var webpack = require('webpack-stream');
var fs = require('fs');


// Build everything
gulp.task('build', gulp.series(gulp.parallel(buildClient, buildServer), runTest));


// Run Tests
function runTest() {
  return gulp.src('test/**/*.js')
    .pipe(mocha());
}
gulp.task('test', gulp.series(runTest));


// Run Linter
function runLint() {
  return gulp.src(['src/**/*.js', 'src/**/**/*.js', '!node_modules/**/*.js', '!bin/**/*.js'])
    .pipe(jshint({
          // TODO: Make this more strict
          esnext: true
      }))
    .pipe(jshint.reporter('default', { verbose: true}))
    .pipe(jshint.reporter('fail'));
}
gulp.task('lint', gulp.series(runLint));


// Build the Client
function buildClient() {
  return gulp.src(['src/client/js/app.js'])
    .pipe(uglify())
    .pipe(webpack(require('./webpack.config.js')))
    .pipe(babel({
      presets: [
        ['es2015', { 'modules': false }]
      ]
    }))
    .pipe(gulp.dest('bin/client/js/'));
}
function moveClient() {
  return gulp.src(['src/client/**/*.*', '!client/js/*.js'])
    .pipe(gulp.dest('./bin/client/'));
}
gulp.task('build-client', gulp.series(runLint, moveClient, buildClient));


// Build the Server
function buildServer() {
  return gulp.src(['src/server/**/*.*', 'src/server/**/*.js'])
    .pipe(babel())
    .pipe(gulp.dest('bin/server/'));
}
gulp.task('build-server', gulp.series(runLint, buildServer));


// Watch for changes
function runWatch() {
  gulp.watch(['src/client/**/*.*'], gulp.series(buildClient, buildServer));
  gulp.watch(['src/server/*.*', 'src/server/**/*.js'], gulp.series(buildServer));
}
gulp.task('watch', gulp.series(gulp.parallel(buildClient, buildServer), runTest, runWatch, run));


// Check for TODO items
function runTodo() {
  return gulp.src('src/**/*.js')
    .pipe(todo())
    .pipe(gulp.dest('./'));
}
gulp.task('todo', gulp.series(runLint, runTodo));


// Run the server
function run() {
    nodemon({
        delay: 10,
        script: './server/server.js',
        cwd: "./bin/",
        args: ["config.json"],
        ext: 'html js css'
    })
    .on('restart', function () {
        util.log('server restarted!');
    });
}
gulp.task('run', gulp.series(gulp.parallel(buildClient, buildServer), run));

var gulp = require('gulp');
var babel = require('gulp-babel');
var jshint = require('gulp-jshint');
var nodemon = require('gulp-nodemon');
var uglify = require('gulp-uglify');
var util = require('gulp-util');
var mocha = require('gulp-mocha');
var todo = require('gulp-todo');
var webpack = require('webpack-stream');
var fs = require('fs');


// Build everything
gulp.task('build', gulp.series(gulp.parallel(buildClient, buildServer), moveClient, runTest));


// Run Tests
function runTest() {
  return gulp.src('test/**/*.js')
    .pipe(mocha());
}
gulp.task('test', gulp.series(runTest));


// Run Linter
function runLint() {
  return gulp.src(['src/**/*.js', 'src/**/**/*.js', '!node_modules/**/*.js', '!bin/**/*.js'])
    .pipe(jshint({
          // TODO: Make this more strict
          esnext: true
      }))
    .pipe(jshint.reporter('default', { verbose: true}))
    .pipe(jshint.reporter('fail'));
}
gulp.task('lint', gulp.series(runLint));


// Build the Client
function buildClient() {
  return gulp.src(['src/client/js/app.js'])
    .pipe(uglify())
    .pipe(webpack(require('./webpack.config.js')))
    .pipe(babel({
      presets: [
        ['es2015', { 'modules': false }]
      ]
    }))
    .pipe(gulp.dest('bin/client/js/'));
}
function moveClient() {
  return gulp.src(['src/client/**/*.*', '!client/js/*.js'])
    .pipe(gulp.dest('./bin/client/'));
}


// Build the Server
function buildServer() {
  return gulp.src(['src/server/**/*.*', 'src/server/**/*.js'])
    .pipe(babel())
    .pipe(gulp.dest('bin/server/'));
}


// Watch for changes
function runWatch() {
  gulp.watch(['src/client/**/*.*'], gulp.series(buildClient, buildServer));
  gulp.watch(['src/server/*.*', 'src/server/**/*.js'], gulp.series(buildServer));
}
gulp.task('watch', gulp.series(gulp.parallel(buildClient, buildServer), runTest, runWatch, run));


// Check for TODO items
function runTodo() {
  return gulp.src('src/**/*.js')
    .pipe(todo())
    .pipe(gulp.dest('./'));
}
gulp.task('todo', gulp.series(runLint, runTodo));


// Run the server
function run() {
    nodemon({
        delay: 10,
        script: './server/server.js',
        cwd: "./bin/",
        args: ["config.json"],
        ext: 'html js css'
    })
    .on('restart', function () {
        util.log('server restarted!');
    });
}
gulp.task('run', gulp.series(moveClient, gulp.parallel(buildClient, buildServer), run));

Fix moveClient in gulpFiled dependency before build