"use strict";

// Load plugins
const autoprefixer = require("gulp-autoprefixer");
const browsersync = require("browser-sync").create();
const cleanCSS = require("gulp-clean-css");
const del = require("del");
const gulp = require("gulp");
const header = require("gulp-header");
const merge = require("merge-stream");
const plumber = require("gulp-plumber");
const rename = require("gulp-rename");
const sass = require("gulp-sass");
const uglify = require("gulp-uglify");
const concat = require('gulp-concat');

// Load package.json for banner
const pkg = require('./package.json');
const publicDirectory = "./Resources/public/";
const vendorDirectory = "./Resources/public/vendor";
const adminDirectory = "./assets/js/Admin";
const adminCssDirectory = "./assets/css/Admin";
const nodeModulesDirectory = "./node_modules";

const adminFiles = require(`${adminDirectory}/included_files.json`);

// Set the banner content
const banner = ['/*\n',
    ' * Comitium - <%= pkg.title %> v<%= pkg.version %> (<%= pkg.homepage %>)\n',
    ' * Copyright 2019-' + (new Date()).getFullYear(), ' <%= pkg.author %>\n',
    ' */\n',
    '\n'
].join('');

// BrowserSync
function browserSync(done) {
    browsersync.init({
        server: {
            baseDir: "./"
        },
        port: 3000
    });
    done();
}

// BrowserSync reload
function browserSyncReload(done) {
    browsersync.reload();
    done();
}

// Clean vendor
function clean() {
    return del([`${vendorDirectory}`]);
}

// Bring third party dependencies from node_modules into vendor directory
function modules() {
    // Bootstrap JS
    var bootstrapJS = gulp.src('./node_modules/bootstrap/dist/js/*')
        .pipe(gulp.dest(`${vendorDirectory}/bootstrap/js`));

    // Bootstrap SCSS
//    var bootstrapSCSS = gulp.src('./node_modules/bootstrap/scss/**/*')
//        .pipe(gulp.dest(`${vendorDirectory}/bootstrap/scss`));
    // ChartJS
    var chartJS = gulp.src('./node_modules/chart.js/dist/*.js')
        .pipe(gulp.dest(`${vendorDirectory}/chart.js`));
    // dataTables
    var dataTables = gulp.src([
        './node_modules/datatables.net/js/*.js',
        './node_modules/datatables.net-bs4/js/*.js',
        './node_modules/datatables.net-bs4/css/*.css'
    ])
        .pipe(gulp.dest(`${vendorDirectory}/datatables`));
    // Font Awesome
    var fontAwesome = gulp.src('./node_modules/@fortawesome/**/*')
        .pipe(gulp.dest(`${vendorDirectory}`));

    // Q
    var Q = gulp.src('./node_modules/q/q.js')
        .pipe(gulp.dest(`${vendorDirectory}/q`));

    //
    var signals = gulp.src('./node_modules/signals/dist/signals.js')
        .pipe(gulp.dest(`${vendorDirectory}/signals`));

    // jQuery Easing
    var jqueryEasing = gulp.src('./node_modules/jquery.easing/*.js')
        .pipe(gulp.dest(`${vendorDirectory}/jquery-easing`));

    // jQuery
    var jquery = gulp.src([
        './node_modules/jquery/dist/cdn/jquery-2.1.3.min.js',
        '!./node_modules/jquery/dist/core.js'
    ])
        .pipe(gulp.dest(`${vendorDirectory}/jquery`));

    // RequireJs
    var requireJs = gulp.src('./node_modules/requirejs/*')
        .pipe(gulp.dest(`${vendorDirectory}/requirejs/`));

    // Select2
    var select2 = gulp.src([
        './node_modules/select2/dist/js/*.js',
        //'./node_modules/select2/dist/css/*.css',
    ])
        .pipe(gulp.dest(`${vendorDirectory}/select2`));

    // moment js
    var moment = gulp.src([
        './node_modules/moment/min/moment.min.js',
    ])
        .pipe(gulp.dest(`${vendorDirectory}/moment`));

    // underscore js
    var underscore = gulp.src([
        './node_modules/underscore/underscore-min.js',
    ])
        .pipe(gulp.dest(`${vendorDirectory}/underscore`));

    // toastr
    var toastr = gulp.src([
        './node_modules/toastr/build/toastr.min.js',
        './node_modules/toastr/build/toastr.min.css',
    ])
        .pipe(gulp.dest(`${vendorDirectory}/toastr`));

    // jquery Autocomplete
    var JqAutocomplete = gulp.src([
        './node_modules/devbridge-autocomplete/dist/jquery.autocomplete.js',
    ])
        .pipe(gulp.dest(`${vendorDirectory}/devbridge-autocomplete`));

    return merge(
        bootstrapJS,
        //bootstrapSCSS,
        chartJS,
        dataTables,
        fontAwesome,
        Q,
        signals,
        jqueryEasing,
        jquery,
        requireJs,
        select2,
        moment,
        underscore,
        toastr,
        JqAutocomplete,
    );
}

function fontAwesomeWebFontsSymLink() {
   del([`${publicDirectory}webfonts`]);
   return gulp.src(`${nodeModulesDirectory}/@fortawesome/fontawesome-free/webfonts/`)
        .pipe(gulp.symlink(`${publicDirectory}webfonts`));
}


// CSS task
function css() {
    return gulp
        .src([
            "./assets/scss/**/*.scss",
        ])
        .pipe(plumber())
        .pipe(sass({
            outputStyle: "expanded",
            includePaths: "./node_modules",
        }))
        .on("error", sass.logError)
        .pipe(autoprefixer({
            cascade: false
        }))
        .pipe(header(banner, {
            pkg: pkg
        }))
        .pipe(concat('main.css'))
        .pipe(rename({
            suffix: ".min"
        }))
        .pipe(cleanCSS())
        .pipe(gulp.dest("./Resources/public/css/"))
        .pipe(browsersync.stream());
}

// JS task
function js() {
    return gulp
        .src(adminFiles.included_files)
        .pipe(uglify())
        .pipe(header(banner, {
            pkg: pkg
        }))
        .pipe(browsersync.stream())
        .pipe(concat('main.js'))
        .pipe(rename({
            suffix: '.min'
        }))
        .pipe(gulp.dest('./Resources/public/js/'));
}

// Watch files
function watchFiles() {
    gulp.watch(`./assets/scss/**/*`, css);
    gulp.watch([`${adminDirectory}/**/*`, `!${adminDirectory}/**/*.min.js`], js);
}

// Define complex tasks
const vendor = gulp.series(
    clean,
    modules,
    fontAwesomeWebFontsSymLink
);
const build = gulp.series(
    vendor,
    gulp.parallel(
        css,
        js
    )
);
const watch = gulp.series(
    build,
    gulp.parallel(
        watchFiles,
        browserSync
    )
);

// Export tasks
exports.css = css;
exports.js = js;
exports.clean = clean;
exports.fontAwesomeWebFontsSymLink = fontAwesomeWebFontsSymLink;
exports.vendor = vendor;
exports.build = build;
exports.watch = watch;
exports.default = build;
