/*
 Copyright (c) 2012, Yahoo! Inc.  All rights reserved.
 Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms.
 */

var nopt = require('nopt'),
    path = require('path'),
    fs = require('fs'),
    Collector = require('../collector'),
    formatOption = require('../util/help-formatter').formatOption,
    util = require('util'),
    utils = require('../object-utils'),
    filesFor = require('../util/file-matcher').filesFor,
    Command = require('./index'),
    configuration = require('../config');

function isAbsolute(file) {
    if (path.isAbsolute) {
        return path.isAbsolute(file);
    }

    return path.resolve(file) === path.normalize(file);
}

function CheckCoverageCommand() {
    Command.call(this);
}

function removeFiles(covObj, root, files) {
    var filesObj = {},
        obj = {};

    // Create lookup table.
    files.forEach(function (file) {
        filesObj[file] = true;
    });

    Object.keys(covObj).forEach(function (key) {
        // Exclude keys will always be relative, but covObj keys can be absolute or relative
        var excludeKey = isAbsolute(key) ? path.relative(root, key) : key;
        // Also normalize for files that start with `./`, etc.
        excludeKey = path.normalize(excludeKey);
        if (filesObj[excludeKey] !== true) {
            obj[key] = covObj[key];
        }
    });

    return obj;
}

CheckCoverageCommand.TYPE = 'check-coverage';
util.inherits(CheckCoverageCommand, Command);

Command.mix(CheckCoverageCommand, {
    synopsis: function () {
        return "checks overall/per-file coverage against thresholds from coverage JSON files. Exits 1 if thresholds are not met, 0 otherwise";
    },

    usage: function () {
        console.error('\nUsage: ' + this.toolName() + ' ' + this.type() + ' <options> [<include-pattern>]\n\nOptions are:\n\n' +
            [
                formatOption('--statements <threshold>', 'global statement coverage threshold'),
                formatOption('--functions <threshold>', 'global function coverage threshold'),
                formatOption('--branches <threshold>', 'global branch coverage threshold'),
                formatOption('--lines <threshold>', 'global line coverage threshold')
            ].join('\n\n') + '\n');

        console.error('\n\n');

        console.error('Thresholds, when specified as a positive number are taken to be the minimum percentage required.');
        console.error('When a threshold is specified as a negative number it represents the maximum number of uncovered entities allowed.\n');
        console.error('For example, --statements 90 implies minimum statement coverage is 90%.');
        console.error('             --statements -10 implies that no more than 10 uncovered statements are allowed\n');
        console.error('Per-file thresholds can be specified via a configuration file.\n');
        console.error('<include-pattern> is a glob pattern that can be used to select one or more coverage files ' +
            'for merge. This defaults to "**/coverage*.json"');

        console.error('\n');
    },

    run: function (args, callback) {

        var template = {
                config: path,
                root: path,
                statements: Number,
                lines: Number,
                branches: Number,
                functions: Number,
                verbose: Boolean
            },
            opts = nopt(template, { v : '--verbose' }, args, 0),
            // Translate to config opts.
            config = configuration.loadFile(opts.config, {
                verbose: opts.verbose,
                check: {
                    global: {
                        statements: opts.statements,
                        lines: opts.lines,
                        branches: opts.branches,
                        functions: opts.functions
                    }
                }
            }),
            includePattern = '**/coverage*.json',
            root,
            collector = new Collector(),
            errors = [];

        if (opts.argv.remain.length > 0) {
            includePattern = opts.argv.remain[0];
        }

        root = opts.root || process.cwd();
        filesFor({
            root: root,
            includes: [ includePattern ]
        }, function (err, files) {
            if (err) { throw err; }
            if (files.length === 0) {
               return callback('ERROR: No coverage files found.');
            }
            files.forEach(function (file) {
                var coverageObject = JSON.parse(fs.readFileSync(file, 'utf8'));
                collector.add(coverageObject);
            });
            var thresholds = {
                global: {
                    statements: config.check.global.statements || 0,
                    branches: config.check.global.branches || 0,
                    lines: config.check.global.lines || 0,
                    functions: config.check.global.functions || 0,
                    excludes: config.check.global.excludes || []
                },
                each: {
                    statements: config.check.each.statements || 0,
                    branches: config.check.each.branches || 0,
                    lines: config.check.each.lines || 0,
                    functions: config.check.each.functions || 0,
                    excludes: config.check.each.excludes || []
                }
            },
                rawCoverage = collector.getFinalCoverage(),
                globalResults = utils.summarizeCoverage(removeFiles(rawCoverage, root, thresholds.global.excludes)),
                eachResults = removeFiles(rawCoverage, root, thresholds.each.excludes);

            // Summarize per-file results and mutate original results.
            Object.keys(eachResults).forEach(function (key) {
                eachResults[key] = utils.summarizeFileCoverage(eachResults[key]);
            });

            if (config.verbose) {
                console.log('Compare actuals against thresholds');
                console.log(JSON.stringify({ global: globalResults, each: eachResults, thresholds: thresholds }, undefined, 4));
            }

            function check(name, thresholds, actuals) {
                [
                    "statements",
                    "branches",
                    "lines",
                    "functions"
                ].forEach(function (key) {
                    var actual = actuals[key].pct,
                        actualUncovered = actuals[key].total - actuals[key].covered,
                        threshold = thresholds[key];

                    if (threshold < 0) {
                        if (threshold * -1 < actualUncovered) {
                            errors.push('ERROR: Uncovered count for ' + key + ' (' + actualUncovered +
                                ') exceeds ' + name + ' threshold (' + -1 * threshold + ')');
                        }
                    } else {
                        if (actual < threshold) {
                            errors.push('ERROR: Coverage for ' + key + ' (' + actual +
                                '%) does not meet ' + name + ' threshold (' + threshold + '%)');
                        }
                    }
                });
            }

            check("global", thresholds.global, globalResults);

            Object.keys(eachResults).forEach(function (key) {
                check("per-file" + " (" + key + ") ", thresholds.each, eachResults[key]);
            });

            return callback(errors.length === 0 ? null : errors.join("\n"));
        });
    }
});

module.exports = CheckCoverageCommand;


