/**

* Note, strictly speaking this isn't a spec.
* But we must run it like one so it occurs in the same context
* as the other tests that have run. In that way, we can
* call out in javascript and get the resulting coverage reports from the instrumented
* files.
*
* Further, when we log the results to console, the file logger captures that.
*/

describe(“jasmine-coverage”, function () {

it("is generating a coverage report", function () {
    // Output the complete line by line coverage report for capture by the file logger
    generateEncodedCoverage();

    // Get the simple percentages for each file
    coverageForAllFiles();
});

});

String.prototype.lpad = function (padString, length) {

var str = this;
while (str.length < length)
    str = padString + str;
return str;

};

function generateEncodedCoverage() {

var rv = {};
for (var file_name in window._$jscoverage) {
    var jscov = window._$jscoverage[ file_name ];
    var file_report = rv[ file_name ] = {
        coverage: new Array(jscov.length),
        source: new Array(jscov.length)
    };
    for (var i = 0; i < jscov.length; ++i) {
        var hit_count = jscov[ i ] !== undefined ? jscov[ i ] : null;

        file_report.coverage[ i ] = hit_count;
        file_report.source[ i ] = jscov.source[ i ];
    }
}
console.log("ENCODED-COVERAGE-EXPORT-STARTS:" + Base64.encode(JSON.stringify(rv)));
console.log("\nENCODED-COVERAGE-EXPORT-ENDS\n");

}

function coverageForAllFiles() {

var totals = { files: 0, statements: 0, executed: 0 };

var output = "Coverage was:\n";

for (var file_name in window._$jscoverage) {
    var jscov = window._$jscoverage[ file_name ];
    var simple_file_coverage = coverageForFile(jscov);

    totals['files']++;
    totals['statements'] += simple_file_coverage['statements'];
    totals['executed'] += simple_file_coverage['executed'];
    if (simple_file_coverage['missing'].length > 0 && JasmineCoverage.warnings) {
        var i, ar = simple_file_coverage['missing'], l = ar.length;
        for (i = 0; i < l; i++) {
            console.log("\033[31m" + "WARNING -- File '" + file_name + "' has no coverage on line: " + ar[i] + "\033[0m");
        }
    }

    var fraction = (simple_file_coverage['executed'] + "/" + simple_file_coverage['statements']).lpad(' ', 10);
    var perc = simple_file_coverage['percentage'];
    if (parseInt(simple_file_coverage['statements']) === 0){
        perc = 100;
    }
    output += fraction + (" = " + perc + "").lpad(' ', 3) + "% for " + file_name + "\n";
}

var coverage = parseInt(100 * totals['executed'] / totals['statements']);
if (isNaN(coverage)) {
    coverage = 0;
}

if (totals['statements'] === 0) {
    console.log("No Javascript was found to test coverage for.");
} else {
    output += ( totals['executed'] + "/" + totals['statements'] + " = " + coverage + "").lpad(' ', 15) + "% Total\n";
    console.log(output);
}

return coverage;

}

function coverageForFile(fileCC) {

var lineNumber;
var num_statements = 0;
var num_executed = 0;
var missing = [];
var length = fileCC.length;
var currentConditionalEnd = 0;
var conditionals = null;
if (fileCC.conditionals) {
    conditionals = fileCC.conditionals;
}
for (lineNumber = 0; lineNumber < length; lineNumber++) {
    var n = fileCC[lineNumber];

    if (lineNumber === currentConditionalEnd) {
        currentConditionalEnd = 0;
    }
    else if (currentConditionalEnd === 0 && conditionals && conditionals[lineNumber]) {
        currentConditionalEnd = conditionals[lineNumber];
    }

    if (currentConditionalEnd !== 0) {
        continue;
    }

    if (n === undefined || n === null) {
        continue;
    }

    if (n === 0) {
        missing.push(lineNumber);
    }
    else {
        num_executed++;
    }
    num_statements++;
}

var percentage = ( num_statements === 0 ? 0 : parseInt(100 * num_executed / num_statements) );

return {
    statements: num_statements,
    executed: num_executed,
    percentage: percentage,
    missing: missing
};

}