
// General
const gulp = require('gulp');
const gracefulFs = require('graceful-fs');
const mapStream = require('map-stream');

// JS
const concat = require('gulp-concat');
const uglify = require('gulp-uglify');

// CSS
const sass = require('gulp-sass');
const postcss = require('gulp-postcss');
const autoprefixer = require('autoprefixer');
const cssnano = require('cssnano');

const config = {
    css: {
        source: './Resources/src/main-css/style.scss',
        dest: './Resources/css'
    },
    js: {
        source: {
            dashboard: [
                './Resources/src/dashboard-analytics/data-range-selector.js',
                './Resources/src/dashboard-analytics/dashboard-analytics.js',
            ],
            main: [
                './Resources/src/main/jquery-2.1.1.js',
                './Resources/src/main/jquery-ui-1.11.2.js',
                './Resources/src/main/timepicker/jquery-ui-timepicker-addon.js',
                './Resources/src/main/slider-access/jquery-ui-sliderAccess.js',
                './Resources/src/main/spectrum/spectrum.js',
                './Resources/src/main/colorbox/jquery.colorbox.min.js',
                './Resources/src/main/chosen/chosen.jquery.min.js',
                './Resources/src/main/jquery.plugins.js',
                './Resources/src/main/jquery.onload.js',
            ]
        },
        dest: './Resources/js'
    }
};

/**
 * Gulp 4 .watch() doesn't update file modified time
 *
 * @link https://github.com/gulpjs/gulp/issues/2193
 */
function updateTimestamp() {
    return mapStream(function (file, callback) {
        if (file.isNull()) {
            return callback(null, file);
        }

        return gracefulFs.utimes(
            file.path,
            new Date(),
            new Date(),
            callback.bind(null, null, file)
        );
    });
}

/**
 * Main CSS
 */
function styleTask() {
    let sassOptions = {
        outputStyle: 'compressed'
    };

    return gulp
        .src(config.css.source, {sourcemaps: true})
        .pipe(sass(sassOptions).on('error', sass.logError))
        .pipe(postcss([
            autoprefixer(),
            cssnano(),
        ]))
        .pipe(updateTimestamp())
        .pipe(gulp.dest(config.css.dest, {sourcemaps: '.'}));
}

/**
 * Dashboard
 */
function dashboardScriptTask() {
    return gulp
        .src(config.js.source.dashboard, {sourcemaps: true})
        .pipe(concat('dashboard-analytics.js'))
        .pipe(uglify())
        .pipe(updateTimestamp())
        .pipe(gulp.dest(config.js.dest, {sourcemaps: '.'}));
}

/**
 * Main
 */
function mainScriptTask() {
    return gulp
        .src(config.js.source.main, {sourcemaps: true})
        .pipe(concat('main.js'))
        .pipe(uglify())
        .pipe(updateTimestamp())
        .pipe(gulp.dest(config.js.dest, {sourcemaps: '.'}));
}

/**
 * Build task
 */
function buildTask(done) {
    return gulp.parallel(
        styleTask,
        mainScriptTask,
        dashboardScriptTask
    )(done);
}

/**
 * Tasks
 */
exports.style = styleTask;
exports.scripts = mainScriptTask;
exports.dashboard = dashboardScriptTask;
exports.default = buildTask;
