/*
 * Copyright (c) 2011-2013, Yahoo! Inc.  All rights reserved.
 * Copyrights licensed under the New BSD License.
 * See the accompanying LICENSE file for terms.
 */
'use strict';

var fs = require('fs'),
    log = require('./log'),
    jslint = require('jslint/lib/linter').lint,
    Scan = require('scanfs'),

    lintopts = require('../config').lintopts,
    jscount,
    pending,
    errors,
    callback;


// scanfs error callback
function onerr(err, pathname) {
    if ('ENOENT' === err.code) {
        callback('Invalid source: ' + pathname);
    } else {
        callback(err);
    }
}

// check if both scanfs and async-readFile have finished
function doneYet(err) {
    var errout,
        msgout;

    pending--;
    if (!pending) {
        errout = Object.keys(errors).length && errors;
        msgout = 'Done. No lint found in ' + jscount + ' js files.';
        callback(errout, msgout);
    }
}

function onignored(err, pathname) {
    log.debug('ignored', pathname);
}

function tally(pathname, offenses) {
    var plural = offenses.length > 1 ? 's' : '';

    log.error('✖ %d error%s in %s', offenses.length, plural, pathname);
    offenses.forEach(function(o) {
        if (!errors[pathname]) {
            errors[pathname] = [];
        }
        errors[pathname].push({
            line: o.line, col: o.character, msg: o.reason, evidence: o.evidence
        });
    });
}

function lint(err, pathname) {
    pending++;
    jscount++;

    function onread(err, contents) {
        var results;

        if (err) {
            // fs.readFile error
            log.error(err);

        } else {
            // linting results
            results = jslint(contents, lintopts);
            if (results.ok) {
            	log.debug('✔ %s', pathname);
            } else {
                tally(pathname, results.errors);
            }
        }
        doneYet(err);
    }

    fs.readFile(pathname, {encoding: 'utf8'}, onread);
}

function isJs(err, pathname, stat) {
    if (stat.isFile() && ('.js' === pathname.slice(-3))) {
        return '.js';
    }
}

function main(sources, exclude, cb) {
    var scan = new Scan(exclude, isJs);

    // up-scope state
    callback = cb || log.info;
    errors = {};
    pending = 1;
    jscount = 0;

    scan.on('.js', lint);
    scan.on('ignored', onignored);
    scan.on('error', onerr);
    scan.on('done', doneYet);
    scan.relatively(sources);
}

module.exports = main;

@@ -704,16 +704,87 @@
 sgout;%0A%0A
+    // fs.readFile error%0A    if (err) %7B%0A        log.error(err);%0A    %7D%0A%0A
     pend
@@ -1596,125 +1596,16 @@
 if (
+!
 err) %7B%0A
-            // fs.readFile error%0A            log.error(err);%0A%0A        %7D else %7B%0A            // linting results%0A
     
@@ -1637,16 +1637,39 @@
 contents
+.replace(/%5E%5C#%5C!.*/, '')
 , lintop
@@ -1719,9 +1719,12 @@
     
+    
-%09
 log.

move fs's log.error, remove shebang, whsp