/* globals jasmine, phantom */
// Verify arguments
var system = require('system');
var args;

if(phantom.args) {
    args = phantom.args;
} else {
    args = system.args.slice(1);//use system args for phantom 2.0+
}

if (args.length === 0) {
    console.log("Simple JasmineBDD test runner for phantom.js");
    console.log("Usage: phantomjs-testrunner.js url_to_runner.html");
    console.log("Accepts http:// and file:// urls");
    console.log("");
    console.log("NOTE: This script depends on jasmine.TrivialReporter being used\non the page, for the DOM elements it creates.\n");
    phantom.exit(2);
}
else {
    var fs = require("fs"),
        pages = [],
        page, address, resultsKey, i, l;


    var setupPageFn = function(p, k) {
        return function() {
            overloadPageEvaluate(p);
            setupWriteFileFunction(p, k, fs.separator);
        };
    };

    for (i = 0, l = args.length; i < l; i++) {
        address = args[i];
        console.log("Loading " + address);

        // if provided a url without a protocol, try to use file://
        address = address.indexOf("://") === -1 ? "file://" + address : address;

        // create a WebPage object to work with
        page = require("webpage").create();
        page.url = address;

        // When initialized, inject the reporting functions before the page is loaded
        // (and thus before it will try to utilize the functions)
        resultsKey = "__jr" + Math.ceil(Math.random() * 1000000);
        page.onInitialized = setupPageFn(page, resultsKey);
        page.open(address, processPage(null, page, resultsKey));
        pages.push(page);

        page.onConsoleMessage = logAndWorkAroundDefaultLineBreaking;
    }

    // bail when all pages have been processed
    setInterval(function(){
        var exit_code = 0;
        for (i = 0, l = pages.length; i < l; i++) {
            page = pages[i];
            if (page.__exit_code === null) {
                // wait until later
                return;
            }
            exit_code |= page.__exit_code;
        }
        phantom.exit(exit_code);
    }, 100);
}

// Thanks to hoisting, these helpers are still available when needed above
/**
 * Logs a message. Does not add a line-break for single characters '.' and 'F' or lines ending in ' ...'
 *
 * @param msg
 */
function logAndWorkAroundDefaultLineBreaking(msg) {
    var interpretAsWithoutNewline = /(^(\033\[\d+m)*[\.F](\033\[\d+m)*$)|( \.\.\.$)/;
    if (navigator.userAgent.indexOf("Windows") < 0 && interpretAsWithoutNewline.test(msg)) {
        try {
            system.stdout.write(msg);
        } catch (e) {
            var fs = require('fs');
            fs.write('/dev/stdout', msg, 'w');
        }
    } else {
        console.log(msg);
    }
}

/**
 * Stringifies the function, replacing any %placeholders% with mapped values.
 *
 * @param {function} fn The function to replace occurrences within.
 * @param {object} replacements Key => Value object of string replacements.
 */
function replaceFunctionPlaceholders(fn, replacements) {
    if (replacements && typeof replacements === "object") {
        fn = fn.toString();
        for (var p in replacements) {
            if (replacements.hasOwnProperty(p)) {
                var match = new RegExp("%" + p + "%", "g");
                do {
                    fn = fn.replace(match, replacements[p]);
                } while(fn.indexOf(match) !== -1);
            }
        }
    }
    return fn;
}

/**
 * Replaces the "evaluate" method with one we can easily do substitution with.
 *
 * @param {phantomjs.WebPage} page The WebPage object to overload
 */
function overloadPageEvaluate(page) {
    page._evaluate = page.evaluate;
    page.evaluate = function(fn, replacements) { return page._evaluate(replaceFunctionPlaceholders(fn, replacements)); };
    return page;
}

/** Stubs a fake writeFile function into the test runner.
 *
 * @param {phantomjs.WebPage} page The WebPage object to inject functions into.
 * @param {string} key The name of the global object in which file data should
 *                     be stored for later retrieval.
 */
// TODO: not bothering with error checking for now (closed environment)
function setupWriteFileFunction(page, key, path_separator) {
    page.evaluate(function(){
        window["%resultsObj%"] = {};
        window.fs_path_separator = "%fs_path_separator%";
        window.__phantom_writeFile = function(filename, text) {
            window["%resultsObj%"][filename] = text;
        };
    }, {resultsObj: key, fs_path_separator: path_separator.replace("\\", "\\\\")});
}

/**
 * Returns the loaded page's filename => output object.
 *
 * @param {phantomjs.WebPage} page The WebPage object to retrieve data from.
 * @param {string} key The name of the global object to be returned. Should
 *                     be the same key provided to setupWriteFileFunction.
 */
function getXmlResults(page, key) {
    return page.evaluate(function(){
        return window["%resultsObj%"] || {};
    }, {resultsObj: key});
}

/**
 * Processes a page.
 *
 * @param {string} status The status from opening the page via WebPage#open.
 * @param {phantomjs.WebPage} page The WebPage to be processed.
 */
function processPage(status, page, resultsKey) {
    if (status === null && page) {
        page.__exit_code = null;
        return function(stat){
            processPage(stat, page, resultsKey);
        };
    }
    if (status !== "success") {
        console.error("Unable to load resource: " + address);
        page.__exit_code = 2;
    }
    else {
        var isFinished = function() {
            return page.evaluate(function(){
                // if there's a JUnitXmlReporter, return a boolean indicating if it is finished
                if (jasmine && jasmine.JUnitXmlReporter && jasmine.JUnitXmlReporter.started_at !== null) {
                    return jasmine.JUnitXmlReporter.finished_at !== null;
                }
                // otherwise, see if there is anything in a "finished-at" element
                return document.getElementsByClassName("finished-at").length &&
                       document.getElementsByClassName("finished-at")[0].innerHTML.length > 0;
            });
        };
        var getResults = function() {
            return page.evaluate(function(){
                return document.getElementsByClassName("description").length &&
                       document.getElementsByClassName("description")[0].innerHTML.match(/(\d+) spec.* (\d+) failure.*/) ||
                       ["Unable to determine success or failure."];
            });
        };
        var timeout = 60000;
        var loopInterval = 100;
        var ival = setInterval(function(){
            if (isFinished()) {
                // get the results that need to be written to disk
                var fs = require("fs"),
                    xml_results = getXmlResults(page, resultsKey),
                    output;
                for (var filename in xml_results) {
                    if (xml_results.hasOwnProperty(filename) && (output = xml_results[filename]) && typeof(output) === "string") {
                        fs.write(filename, output, "w");
                    }
                }

                // print out a success / failure message of the results
                var results = getResults();
                var failures = Number(results[2]);
                if (failures > 0) {
                    page.__exit_code = 1;
                    clearInterval(ival);
                }
                else {
                    page.__exit_code = 0;
                    clearInterval(ival);
                }
            }
            else {
                timeout -= loopInterval;
                if (timeout <= 0) {
                    console.log('Page has timed out; aborting.');
                    page.__exit_code = 2;
                    clearInterval(ival);
                }
            }
        }, loopInterval);
    }
}
