#!/usr/bin/env gjs

const GLib = imports.gi.GLib;
const Gio = imports.gi.Gio;

GLib.setenv("GJS_DEBUG_TOPICS", "", true);

function getDependencies(content, sciptPath) {
    let src = '';
    let dependencies = String(content).match(/^\/\/ @require\s.+\.js$/gm);
    let originScript = Gio.file_new_for_path(sciptPath);
    let topsrc = originScript.get_parent().get_parent();
    for (let i = 0; dependencies && i < dependencies.length; i++) {
        let name = dependencies[i].match(/[^\s]+\.js$/)[0];
        let file = Gio.file_new_for_path(
            '/usr/share/unity-webapps/userscripts/common/' + name)

        lint('/usr/share/unity-webapps/userscripts/common/' + name);

        let [res, content] = GLib.file_get_contents(file.get_path());
        src += content + '\n';
    }

    return [src.split('\n').length, src];
}

function lint(sciptPath) {
    let [res, content] = GLib.file_get_contents(
        '/usr/share/unity-webapps/tools/jslint.js');
    eval(String(content));

    [res, content] = GLib.file_get_contents(sciptPath);

    let [linesCount, header] = getDependencies(content, sciptPath);
    header = 'var jQuery = {}, WebappsGettextDict = {}, CustomEvent = {}, reportTestState = function () {}, Unity = {}, XPathResult = {}, unescape = function () {}, assert = function () {}, assertTrue = function () {}, assertFalse = function () {}, assertEquals = function () {}, assertNotEquals = function () {}, assertNull = function () {}, assertNotNull = function () {}, assertUndefined = function () {}, assertNotUndefined = function () {}, assertNaN = function () {}, assertNotNaN = function () {}, fail = function () {}, makeAuthorizer = function () {}, unsafeWindow = {};\n' + header;
    JSLINT(String(header + content),
           { browser: true, sloppy: true, plusplus: true, regexp: true,
             es5: true, vars: true, devel: true, nomen: true, maxerr: 999 });

    print('style_checker.js: checking ' + sciptPath);

    let count = 0;
    for (let i = 0; i < JSLINT.errors.length; i++) {
        if (!JSLINT.errors[i])
            continue;
        if (JSLINT.errors[i].line <= linesCount) {
            if (JSLINT.errors[i].reason.match(/^Stopping/)) {
                print("TOO MUCH ERRORS. Stopping");
            }
            continue;
        }
        print(sciptPath + ':' + (JSLINT.errors[i].line - linesCount) + '->' + JSLINT.errors[i].reason);
        count++;
    }

    return count;
}

if (ARGV.length != 1) {
    printerr("Usage: gjslint.js filename");
} else {
    if (lint(ARGV[0]))
        throw "";
}
