const { src, dest, series } = require('gulp');
const log = require('fancy-log');
const concat = require('gulp-concat');
const rename = require('gulp-rename');
const del = require('del');
const { exec } = require('child_process');
const replace = require('gulp-replace');

const LOCALES = ['en-GB', 'es-ES', 'it-IT', 'en-IE', 'en-AU', 'en-NZ', 'da-DK'];

const PATHS = {
    vueSrcFolder: './static/src',
    tempDistFolder: './static/.tmp-dist',
    tempVueFolder: './static/.tmp-vue',
    rootDistFolder: './dist/static',
    nodeModulesFolder: './node_modules'
};

/**
 * Remove any folders used by the gulpfile to generate the static files
 */
function cleanTmpFolders () {
    log('clear .tmp folders and dest folder');
    return del([PATHS.tempVueFolder, PATHS.tempDistFolder, `${PATHS.nodeModulesFolder}/.cache/vue-loader`], { force: true });
}

/**
 * Remove the vue-cli cache to ensure it picks up prop changes from setVueProps()
 */
function clearVueCliCache () {
    log(`clear ${PATHS.nodeModulesFolder}/.cache`);
    return del([`${PATHS.nodeModulesFolder}/.cache/vue-loader`], { force: true });
}

/**
 * Sets the locale prop in the Vue template before compilation
 * @param {String} locale - The country langauge code to update
 */
function setVueProps (locale) {
    return () => {
        log(`update locale prop -  ${locale}`);

        return src([`${PATHS.vueSrcFolder}/App.vue`])
            .pipe(replace(/locale='(.*?)'(.*?)/g, `locale='${locale}'`))
            .pipe(dest(PATHS.vueSrcFolder));
    };
}

/**
 * Run vue-cli build to compile using pre-render package into a temp folder
 */
function vueBuild () {
    log('running vue-cli-service build');
    return exec(`vue-cli-service build --dest ${PATHS.tempVueFolder} ./static/src/main.js`, (err, stdout, stderr) => {
        log(stdout);
        log(stderr);
        if (err) { log(err); }
    });
}

/**
 * Rename and move the CSS file using the locale to name it and move to the temp dist folder
 * @param {String} locale - The country langauge code to update
 */
function moveCSS (locale) {
    return () => {
        log(`move css and rename to: ${locale}.css`);

        return src(`${PATHS.tempVueFolder}/css/*.css`)
            .pipe(rename(`${locale}.css`))
            .pipe(dest(PATHS.tempDistFolder));
    };
}

/**
 * Combine the JS files generated by vueBuild() into a single file using the locale to name it and move to the temp dist folder
 * @param {String} locale - The country langauge code to update
 */
function concatJS (locale) {
    return () => {
        log(`move js into one file: ${locale}.js`);

        return src(`${PATHS.tempVueFolder}/js/*.js`)
            .pipe(concat(`${locale}.js`))
            .pipe(dest(PATHS.tempDistFolder));
    };
}

/**
 * Move the final static files to the root dist folder f-cookie-banner/dist/static
 */
function moveFilesToRootDist () {
    log('move generated files to ./dist/static');
    return src(`${PATHS.tempDistFolder}/**`)
            .pipe(dest(PATHS.rootDistFolder));
}

/**
 * Gulp task to generate compiled static files for each locale
 */
function defaultTask () {
    const tasks = LOCALES.map(locale => [
        clearVueCliCache,
        setVueProps(locale),
        vueBuild,
        moveCSS(locale),
        concatJS(locale)
    ]);

    return series(
        cleanTmpFolders,
        ...tasks,
        moveFilesToRootDist,
        cleanTmpFolders
    );
}

exports.default = defaultTask();
