const {src, dest, series} = require('gulp');
const del = require('del');
const ts = require('gulp-typescript');
const exec = require('child_process').exec;
const sass = require('gulp-sass');
const fs = require('fs');
const path = require('path');
sass.compiler = require('node-sass');
let tsSource = ts.createProject('tsconfig.json')

function clean(cb) {
    del(['build/*']);
    del(['out/*']);
    cb();
}

function validateConfigSources(cb) {
    console.log("Validating source json files...");
    let confBase = "src/assets/conf/";
    let configsToCheck = ["resources-landing-page.json"];
    for (let i = 0, l = configsToCheck.length; i < l; i++) {
        let currConfig = configsToCheck[i];
        let configContent = fs.readFileSync(path.join(confBase, currConfig));
        let conf = JSON.parse(configContent.toString());
        let keys = Object.keys(conf);
        let fileSpecificRules = validationRules[currConfig];
        for (let j = 0, m = keys.length; j < m; j++) {
            let key = keys[i];
            let content = conf[key];
            let rules = fileSpecificRules[key];
            let ruleKeys = Object.keys(rules);
            for (let k = 0, n = ruleKeys.length; k < n; k++) {
                let rule = ruleKeys[k];
                let ruleValidator = rules[rule];
                for (let x = 0, y = content.length; x < y; x++) {
                    let renderObj = content[x];
                    let ruleSubject = renderObj[rule];
                    let validResults = ruleValidator(ruleSubject, currConfig, rule);
                    if (null !== validResults) {
                        cb(validResults);
                    }
                }
            }
        }
    }
    cb();
}

let deploy = () => {

};

function conf() {
    return src(['src/assets/**/*', '!src/assets/**/*.scss'], {base: 'src/assets'})
        .pipe(dest('build/assets/'));
}

function style() {
    return src('node_modules/bootstrap/dist/css/bootstrap.css')
        .pipe(dest('build/assets/pages/styles/'));
}

function scss() {
    return src('src/assets/pages/styles/*.scss',)
        .pipe(sass.sync().on('error', sass.logError))
        .on('error', () => {
            process.exit(1)
        })
        .pipe(dest('build/assets/pages/styles/'));
}

function tests() {
    return src('tests/*',)
        .pipe(dest('build/tests/'));
}

function root() {
    return src('src/*.js')
        .pipe(dest('build/'));
}

function pkg() {
    return src('package*')
        .pipe(dest('build/'));
}

function typescript() {
    return tsSource.src()
        .pipe(tsSource()).on('error', () => {
            process.exit(1)
        })
        .js
        .pipe(dest('build/util/'));
}

function dependencies(cb) {
    // Installs dependencies into build folder
    exec('npm --prefix ./build install ./build --production', './node_modules/.bin/electron-rebuild -m ./build/node_modules',
        (err, stdout, stderr) => {
            console.log(stdout);
            console.log(stderr)
            cb(err);
        });
}


let stringLengthRule = function (str, fileName, rulename) {
    let maxLen = 124;
    if (str.length > maxLen) {
        return Error(`Content too long in ${fileName}:${rulename}! Expected maximum of ${maxLen} characters, got ${str.length} "${str}"`)
    }
}

let validationRules = {
    "resources-landing-page.json": {
        "grid-container": {
            "description": stringLengthRule
        }
    }
}


exports.clean = clean;

exports.default = series(validateConfigSources, conf, style, scss, root, pkg, typescript, dependencies);

exports.tests = series(validateConfigSources, conf, style, scss, root, pkg, typescript, dependencies, tests);

exports.runFast = series(validateConfigSources, conf, style, scss, root, pkg)

exports.deploy = series(clean, validateConfigSources, conf, style, scss, root, pkg, typescript, dependencies, deploy);