/*global JSLINT */
/*jslint white: true, rhino: true */
/**
 * @fileOverview Provides a JSLint console for Rhino.
 * <p>Usage: <code>java -jar lib/js.jar lib/jslint-console.js lib/fulljslint.js src/testFile1.js src/testFile2.js</code></p>
 * @author Mehdi Kabab <http://pioupioum.fr/>
 * @version 0.1.1 (2010-06-24)
 */
/**
 * @license Copyright (c) 2010 Mehdi Kabab <http://pioupioum.fr/>.
 *
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation
 * files (the "Software"), to deal in the Software without
 * restriction, including without limitation the rights to use,
 * copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following
 * conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 */
 
// Loads the JSLint script given as first argument.
load(arguments.splice(0, 1));
 
(function (scripts) {
    var i,
        indentLen = 0;
 
    /**
     * Returns the string repeated multiplier times.
     * @param {Number} multiplier Number of time the string should be repeated.
     * @this {String}
     * @return Returns the repeated string.
     * @type String
     * @addon
     */
    String.prototype.repeat = function (multiplier) {
        if (0 > multiplier) {
            multiplier = 0;
        }
        return new Array(1 + multiplier).join(this);
    };
 
    /**
     * Cleans evidence message and assign <code>identLen</code>.
     * @private
     * @param {String} str The full message.
     * @param {String} p1 Possible identation.
     * @param {String} p2 The message content.
     * @returns The message content
     * @type String
     */
    function cleanEvidence(str, p1, p2) {
        indentLen = p1.length;
        return p2;
    } // cleanEvidence
 
    /**
     * Check quality code of the given script.
     * @private
     * @param {String} jsfile File to check.
     * @requires JSLINT
     * @requires String#repeat()
     */
    function lint(jsfile) {
        var i,
            input,
            e,
            errLen,
            errTag = "[ERROR] ",
            found = 0;
 
        print("Running JSLint on: " + jsfile);
        input = readFile(jsfile);
        if (!input) {
            print(errTag + "Couldn't open file.");
            quit(1);
        }
 
        if (!JSLINT(input, { browser: true, rhino: true, laxbreak: true,
            onevar: true, undef: true, nomen: true, eqeqeq: true, bitwise: true,
            regexp: false, newcap: true,
            predef: ['window', 'escape', 'unescape']
        })) {
            for (i = 0, errLen = JSLINT.errors.length; i < errLen; ++i) {
                e = JSLINT.errors[i];
                if (e) {
                    found += 1;
                    if ("% scanned)." !== e.reason.substr(-11)) {
                        print(errTag + e.reason.replace(/\.$/, '') +
                            " on line " + e.line + " character " + e.character + ".");
                        if ("" !== e.evidence) {
                            print(" ".repeat(errTag.length) +
                                (e.evidence || '').replace(/^(\s*)(\S*(\s+\S+)*)\s*$/, cleanEvidence));
                            print(" ".repeat(errTag.length) +
                                ".".repeat(e.character - indentLen - 1) + "^");
                        }
                    } else {
                        print(errTag + e.reason);
                    }
                }
            }
            print("=> " + found + " error(s) found.\n");
            quit(2);
        } else {
            print("OK\n");
        }
    } // lint
 
    if (!scripts[0]) {
        print("Usage: jslint-console.js fulljslint.js file1.js[ file2.js]");
        quit(1);
    }
 
    for (i = 0; i < scripts.length; ++i) {
        lint(scripts[i]);
    }
}(arguments));
