// Magnitude gives a best guess estimate of the runtime of a function.
// Magnitude.run can be called multiple times in a single test if desired.
//
// Usage:
// <script src="../resources/magnitude-perf.js"></script>
// <script>
// ...
// Magnitude.run(setup, test, expected)
// </script>
//
// -setup is the function to run once before the test-loop. It takes a magnitude argument
// that is the value of "n".
// -test is the code whose runtime is being tests. It also takes a magnitude argument.
// -expected is one of the run-time constants listed below (e.g. Magnitude.CONSTANT).

if (window.testRunner)
    testRunner.dumpAsText();

// Namespace.
var Magnitude = {};

// The description of what this test is testing. Gets prepended to the dumped markup.
Magnitude.description = function(description)
{
    Magnitude._log(description);
}

Magnitude.numPoints = 8;
Magnitude.millisecondsPerIteration = 25;
Magnitude.initialMagnitude = 1;

Magnitude.CONSTANT = "O(1)";
Magnitude.LINEAR = "O(n)";
Magnitude.LOGARITHMIC = "O(log n)";
Magnitude.POLYNOMIAL = ">=O(n^2)";
Magnitude.INDETERMINATE = "indeterminate result";

Magnitude._order = {}
Magnitude._order[Magnitude.CONSTANT] = 1;
Magnitude._order[Magnitude.LINEAR] = 2;
Magnitude._order[Magnitude.LOGARITHMIC] = 3;
Magnitude._order[Magnitude.POLYNOMIAL] = 4;
Magnitude._order[Magnitude.INDETERMINATE] = 5;

Magnitude._log = function(msg)
{
    if (!Magnitude._container)
        Magnitude._container = document.createElement('pre');
    Magnitude._container.appendChild(document.createTextNode(msg + '\n'));
}

Magnitude._debug = function(msg)
{
    Magnitude._debugLog += msg + '\n';
}

Magnitude.run = function(setup, test, expected)
{
    Magnitude._debugLog = "\nDEBUG LOG:\n";

    Magnitude._magnitudes = [];
    for (var i = Magnitude.initialMagnitude; i < Magnitude.numPoints + Magnitude.initialMagnitude; i++)
        Magnitude._magnitudes.push(Math.pow(2, i));

    var numTries = 3;
    Magnitude._run(setup, test, expected, numTries);
}

Magnitude._run = function(setup, test, expected, numTriesLeft)
{
    Magnitude._iterations = {};
    for (var i = 0; i < Magnitude._magnitudes.length; i++) {
        var magnitude = Magnitude._magnitudes[i];
        Magnitude._iterations[magnitude] = Magnitude._runIteration(setup, test, magnitude);
    }

    Magnitude._logIterationInfo();

    numTriesLeft--;
    var bigO = Magnitude._bigOGuess();
    var passed = Magnitude._order[bigO] <= Magnitude._order[expected];
    if (passed || numTriesLeft < 1) {
        Magnitude._log(passed ? "PASS" : "FAIL: got " + bigO + " expected " + expected);

        // By default don't log detailed information to layout test results to keep expected results
        // consistent from run to run.
        if (!window.testRunner || !passed)
            Magnitude._log(Magnitude._debugLog);
    } else {
        Magnitude._debug("numTriesLeft: " + numTriesLeft);
        arguments.callee(setup, test, expected, numTriesLeft);
    }
}

Magnitude._rSquared = function(opt_xTransform, opt_yTransform)
{
    // Implement http://www.easycalculation.com/statistics/learn-correlation.php.
    // x = magnitude
    // y = iterations
    var sumX = 0;
    var sumY = 0;
    var sumXSquared = 0;
    var sumYSquared = 0;
    var sumXTimesY = 0;

    var numPoints = Magnitude._magnitudes.length;

    for (var i = 0; i < numPoints; i++) {
        var x = Magnitude._magnitudes[i];
        if (opt_xTransform)
            x = opt_xTransform(x);

        var y = Magnitude.millisecondsPerIteration / Magnitude._iterations[Magnitude._magnitudes[i]];
        if (opt_yTransform)
            y = opt_yTransform(y);

        sumX += x;
        sumY += y;
        sumXSquared += x * x;
        sumYSquared += y * y;
        sumXTimesY += x * y;
    }

    var r = (numPoints * sumXTimesY - sumX * sumY) /
        Math.sqrt((numPoints * sumXSquared - sumX * sumX) *
                  (numPoints * sumYSquared - sumY * sumY));

    if (isNaN(r) || r == Math.Infinity)
        r = 0;

    rSquared = r * r;

    var slope = (numPoints * sumXTimesY - sumX * sumY) /
        (numPoints * sumXSquared - sumX * sumX);
    var intercept = sumY / numPoints - slope * sumX / numPoints;
    Magnitude._debug("numPoints " + numPoints + " slope " + slope + " intercept " + intercept + " rSquared " + rSquared);

    return rSquared;
}

Magnitude._logIterationInfo = function()
{
    var iterationsArray = [];
    for (var i = 0; i < Magnitude._magnitudes.length; i++) {
        var magnitude = Magnitude._magnitudes[i];
        var iterations = Magnitude._iterations[magnitude];
        iterationsArray.push(iterations);
    }

    // Print out the magnitudes/arrays in CSV to afford easy copy-paste to a charting application.
    Magnitude._debug("magnitudes: " + Magnitude._magnitudes.join(','));
    Magnitude._debug("iterations: " + iterationsArray.join(','));
}

Magnitude._bigOGuess = function()
{
    var rSquared = Magnitude._rSquared();
    var rSquaredXLog = Magnitude._rSquared(Math.log);
    var rSquaredXYLog = Magnitude._rSquared(Math.log, Math.log);
    Magnitude._debug("rSquared " + rSquared + " rSquaredXLog " + rSquaredXLog + " rSquaredXYLog " + rSquaredXYLog);

    var rSquaredMax = Math.max(rSquared, rSquaredXLog, rSquaredXYLog);

    var bigO = Magnitude.INDETERMINATE;

    // FIXME: These numbers were chosen arbitrarily.
    // Are there a better value to check against? Do we need to check rSquaredMax?
    if (rSquared < 0.8 && rSquaredMax < 0.9)
        bigO = Magnitude.CONSTANT;
    else if (rSquaredMax > 0.9) {
        if (rSquared == rSquaredMax)
            bigO = Magnitude.LINEAR;
        else if (rSquaredXLog == rSquaredMax)
            bigO = Magnitude.LOGARITHMIC;
        else if (rSquaredXYLog == rSquaredMax)
            bigO = Magnitude.POLYNOMIAL;
    }

    return bigO;
}

Magnitude._runIteration = function(setup, test, magnitude)
{
    setup(magnitude);

    var debugStr = 'run iteration. magnitude ' + magnitude;
    if (window.GCController) {
        if (GCController.getJSObjectCount)
            debugStr += " jsObjectCountBefore " + GCController.getJSObjectCount();

        // Do a gc to reduce likelihood of gc during the test run.
        // Do multiple gc's for V8 to clear DOM wrappers.
        GCController.collect();
        GCController.collect();
        GCController.collect();

        if (GCController.getJSObjectCount)
            debugStr += " jsObjectCountAfter " + GCController.getJSObjectCount();
    }

    Magnitude._debug(debugStr);

    var iterations = 0;
    var nowFunction = window.performance && window.performance.now ? window.performance.now.bind(window.performance) : Date.now;
    var start = nowFunction();
    while (nowFunction() - start < Magnitude.millisecondsPerIteration) {
        test(magnitude);
        iterations++;
    }
    return iterations;
}

window.addEventListener('load', function() {
    // FIXME: Add Magnitude.waitUntilDone/notifyDone for tests that need to operate after the load event has fired.
    if (window.testRunner)
        document.body.innerHTML = '';
    document.body.appendChild(Magnitude._container);
}, false);
