﻿var exec = require('child_process').exec;
var fs = require('fs');
var mkdirp = require('mkdirp');
var plugins = require('gulp-load-plugins')();
var defaults = require('lodash.defaults');

module.exports = function (gulp, config) {
    // Set config defaults.
    config = config || {};
    defaults(config,
        {
            paths: {
                src: ['app.js'],
                test: ['test/**/*spec.js', 'test/**/*test.js']
            }
        },
        {lintReporter: 'checkstyle'},
        {lintOutputDir: './lint-results'},
        {lintOutputFile: 'results.xml'},
        {testOutputDir: './test-results'},
        {testOutputFile: 'results.xml'},
        {coverageReporter: 'mocha-jenkins-reporter'},
        {coverageOutputFormat: ['cobertura']}
    );

    /**
     * Runs run-lint linter on source code
     * and prints a report.
     *
     * `gulp run-lint`
     */
    gulp.task('run-lint', () =>
        gulp.src([].concat(config.paths.src, config.paths.test))
            .pipe(plugins.xo())
    );

    /**
     * Runs run-lint linter on source code
     * and prints a report that can be consumed by Jenkins.
     *
     * `gulp run-lint-jenkins`
     */
    gulp.task('run-lint-jenkins', () => {
        var params = [].concat(config.paths.src, config.paths.test, ['--reporter=' + config.lintReporter])
            .join(' ');
        exec('xo ' + params, function (err, stdout) {
            if (err) {
                return console.error(err);
            }

            // Make sure the output directory exists.
            mkdirp(config.lintOutputDir, function (err) {
                if (err) {
                    return console.error(err);
                }

                fs.writeFile(config.lintOutputDir + '/' + config.lintOutputFile, stdout, function (err) {
                    if (err) {
                        return console.error(err);
                    }
                });
            });
        });
    });

    /**
     * Runs unit tests and prints out
     * a report.
     *
     * `gulp run-tests`
     */
    gulp.task('run-tests', (cb) => {
        process.env.NODE_ENV = 'test';
        gulp.src(config.paths.src)
            .pipe(plugins.istanbul()) // Covering files
            .pipe(plugins.istanbul.hookRequire()) // Force `require` to return covered files
            .on('finish', function () {
                gulp.src(config.paths.test)
                    .pipe(plugins.mocha())
                    .pipe(plugins.istanbul.writeReports({
                        reporters: ['text', 'text-summary']
                    })) // Creating the reports after tests ran
                    .on('end', cb);
            });
    });

    /**
     * Runs unit tests and prints out
     * a report.
     *
     * `gulp run-tests-jenkins`
     */
    gulp.task('run-tests-jenkins', (cb) => {
        process.env.NODE_ENV = 'test';
        gulp.src(config.paths.src)
            .pipe(plugins.istanbul()) // Covering files
            .pipe(plugins.istanbul.hookRequire()) // Force `require` to return covered files
            .on('finish', function () {
                gulp.src(config.paths.test)
                    .pipe(plugins.mocha({
                        reporter: config.coverageReporter,
                        reporterOptions: {
                            junit_report_path: config.testOutputDir + '/' + config.testOutputFile // eslint-disable-line camelcase
                        }
                    }))
                    .pipe(plugins.istanbul.writeReports({
                        reporters: config.coverageOutputFormat
                    })) // Creating the reports after tests ran
                    .on('end', cb);
            });
    });

    /**
     * Lints source code and runs test suite.
     *
     * `gulp validate`
     */
    gulp.task('validate', ['run-lint', 'run-tests']);

    /**
     * Lints source code and runs test suite.
     *
     * `gulp validate-jenkins`
     */
    gulp.task('validate-jenkins', ['run-lint-jenkins', 'run-tests-jenkins']);

    /**
     * Watches sources and runs linter on
     * changes.
     *
     * `gulp watch`
     */
    gulp.task('watch', () => gulp.watch(config.paths.src, ['validate']));
};

@@ -2208,34 +2208,16 @@
 anbul())
- // Covering files
 %0A       
@@ -2262,51 +2262,8 @@
 e())
- // Force %60require%60 to return covered files
 %0A   
@@ -2531,48 +2531,8 @@
  %7D))
- // Creating the reports after tests ran
 %0A   
@@ -2859,26 +2859,8 @@
 l())
- // Covering files
 %0A   
@@ -2909,51 +2909,8 @@
 e())
- // Force %60require%60 to return covered files
 %0A   
@@ -3436,16 +3436,16 @@
 tFormat%0A
+
         
@@ -3463,48 +3463,8 @@
  %7D))
- // Creating the reports after tests ran
 %0A   

Normalize comments.