import gulp from 'gulp';
import del from 'del';
import sourcemaps from 'gulp-sourcemaps';
import webpack from 'webpack-stream';
import babel from 'gulp-babel';
import runSequence from 'run-sequence';
import path from 'path';
import childProcess from 'child_process';
import eslint from 'gulp-eslint';
import mocha from 'gulp-mocha';

const PATHS = setUpPaths();

gulp.task('default', ['build']);

gulp.task('build', callback => {
    runSequence('clean', ['build-cli', 'build-app'], callback);
});

gulp.task('build-app', ['build-static'], () => {
    return gulp.src(PATHS.APP_MAIN_JS)
        .pipe(webpack(require(PATHS.WEBPACK_CONFIG)))
        .pipe(gulp.dest(PATHS.APP_DEST));
});

gulp.task('clean', callback => {
    del(PATHS.CLI_DEST).then(() => {
        del(PATHS.APP_DEST).then(() => {
            callback();
        });
    });
});

gulp.task('build-cli', done => {
    return gulp.src(PATHS.CLI_SRC_JS)
        .pipe(sourcemaps.init())
        .pipe(babel())
        .on('error', done)
        .pipe(sourcemaps.write('.'))
        .pipe(gulp.dest('lib'));
});

gulp.task('build-static', ['build-static-js', 'build-static-not-js']);

gulp.task('build-static-not-js', () => {
    return gulp.src([PATHS.APP_STATIC_ALL, '!**/*.js'])
        .pipe(gulp.dest(PATHS.APP_STATIC_DEST));
});

gulp.task('build-static-js', done => {
    return gulp.src(PATHS.APP_STATIC_JS)
        .pipe(sourcemaps.init())
        .pipe(babel())
        .on('error', done)
        .pipe(sourcemaps.write('.'))
        .pipe(gulp.dest(PATHS.APP_STATIC_DEST));
});

gulp.task('watch', ['build'], () => {
    var handleError = function(error) {
        console.error(error);
    };
    gulp.watch(PATHS.APP_ALL, ['build-app'])
        .on('error', handleError);

    gulp.watch(PATHS.CLI_SRC_JS, ['build-cli'])
        .on('error', handleError);
});

gulp.task('publish', done => {
    childProcess.spawn('npm', ['publish'], {stdio: 'inherit'})
        .on('close', done);
});

gulp.task('release', callback => {
    return runSequence('test', 'lint', 'build', 'publish', callback);
});

gulp.task('lint', () => {
    return gulp.src(['**/*.js', '!node_modules/**', '!app/node_modules/**', '!app/lib/**', '!lib/**', '!built-tests/**'])
        .pipe(eslint())
        .pipe(eslint.format())
        .pipe(eslint.failAfterError());
});

gulp.task('build-tests', done => {
    return gulp.src(PATHS.TEST_SRC_JS)
        .pipe(sourcemaps.init())
        .pipe(babel())
        .on('error', done)
        .pipe(sourcemaps.write('.'))
        .pipe(gulp.dest(PATHS.TEST_DEST));
});

gulp.task('test', ['build', 'build-tests'], () => {
    return gulp.src(PATHS.TEST_DEST_JS, {read: false})
        .pipe(mocha());
});

gulp.task('ci', callback => {
    return runSequence('test', 'lint', callback);
});

function setUpPaths() {
    const paths = {
        WEBPACK_CONFIG: './webpack.config.js',
        APP_SRC: 'app/src',
        APP_DEST: 'app/lib',
        CLI_SRC: 'src',
        CLI_DEST: 'lib',
        TEST_SRC: 'test',
        TEST_DEST: 'built-tests'
    };

    paths.APP_MAIN_JS = path.join(paths.APP_SRC, '/main.js');
    paths.APP_ALL = paths.APP_SRC + '/**/*';
    paths.APP_STATIC_ALL = path.join(paths.APP_SRC, 'static') + '/**/*';
    paths.APP_STATIC_JS = path.join(paths.APP_SRC, 'static') + '/**/*.js';
    paths.APP_STATIC_DEST = path.join(paths.APP_DEST, 'static');
    paths.CLI_SRC_JS = paths.CLI_SRC + '/**/*.js';
    paths.TEST_SRC_JS = paths.TEST_SRC + '/**/*.js';
    paths.TEST_DEST_JS = paths.TEST_DEST + '/**/*.js';

    return paths;
}

@@ -473,16 +473,31 @@
 ild-app'
+, 'build-tests'
 %5D, callb
@@ -494,32 +494,32 @@
 s'%5D, callback);%0A
-
 %7D);%0A%0Agulp.task('
@@ -799,32 +799,82 @@
 T).then(() =%3E %7B%0A
+            del(PATHS.TEST_DEST).then(() =%3E %7B%0A    
             call
@@ -881,16 +881,32 @@
 back();%0A
+            %7D);%0A
         
@@ -1906,16 +1906,103 @@
 eError);
+%0A%0A    gulp.watch(PATHS.TEST_SRC_JS, %5B'build-tests'%5D)%0A        .on('error', handleError);
 %0A%7D);%0A%0Agu
@@ -2718,32 +2718,32 @@
 ST_DEST));%0A%7D);%0A%0A
+
 gulp.task('test'
@@ -2752,31 +2752,16 @@
 %5B'build'
-, 'build-tests'
 %5D, () =%3E

Update gulpfile - Build tests in `gulp build` - Watch test files - Clean test files as well