// Copyright (C) 2012 Google Inc. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

//////////////////////////////////////////////////////////////////////////////
// CONSTANTS
//////////////////////////////////////////////////////////////////////////////
var FORWARD = 'forward';
var BACKWARD = 'backward';
var TEST_URL_BASE_PATH_FOR_BROWSING = 'http://src.chromium.org/viewvc/blink/trunk/LayoutTests/';
var TEST_URL_BASE_PATH_FOR_XHR = 'http://src.chromium.org/blink/trunk/LayoutTests/';
var TEST_RESULTS_BASE_PATH = 'https://storage.googleapis.com/chromium-layout-test-archives/';
var GPU_RESULTS_BASE_PATH = 'http://chromium-browser-gpu-tests.commondatastorage.googleapis.com/runs/'

var RELEASE_TIMEOUT = 6;
var DEBUG_TIMEOUT = 12;
var SLOW_MULTIPLIER = 5;

// FIXME: Figure out how to make this not be hard-coded.
// Probably just include in the results.json files and get it from there.
var VIRTUAL_SUITES = {
    'virtual/gpu/fast/canvas': 'fast/canvas',
    'virtual/gpu/canvas/philip': 'canvas/philip',
    'virtual/threaded/compositing/visibility': 'compositing/visibility',
    'virtual/threaded/compositing/webgl': 'compositing/webgl',
    'virtual/gpu/fast/hidpi': 'fast/hidpi',
    'virtual/softwarecompositing': 'compositing',
    'virtual/deferred/fast/images': 'fast/images',
    'virtual/gpu/compositedscrolling/overflow': 'compositing/overflow',
    'virtual/gpu/compositedscrolling/scrollbars': 'scrollbars',
};

var ACTUAL_RESULT_SUFFIXES = ['expected.txt', 'expected.png', 'actual.txt', 'actual.png', 'diff.txt', 'diff.png', 'wdiff.html', 'crash-log.txt'];

var EXPECTATIONS_ORDER = ACTUAL_RESULT_SUFFIXES.filter(function(suffix) {
    return !string.endsWith(suffix, 'png');
}).map(function(suffix) {
    return suffix.split('.')[0]
});

var resourceLoader;

function generatePage(historyInstance)
{
    if (historyInstance.crossDashboardState.useTestData)
        return;

    document.body.innerHTML = '<div id="loading-ui">LOADING...</div>';
    resourceLoader.showErrors();

    // tests expands to all tests that match the CSV list.
    // result expands to all tests that ever have the given result
    if (historyInstance.dashboardSpecificState.tests || historyInstance.dashboardSpecificState.result)
        generatePageForIndividualTests(individualTests());
    else
        generatePageForBuilder(historyInstance.dashboardSpecificState.builder || currentBuilderGroup().defaultBuilder());

    for (var builder in currentBuilders())
        processTestResultsForBuilderAsync(builder);

    postHeightChangedMessage();
}

function handleValidHashParameter(historyInstance, key, value)
{
    switch(key) {
    case 'result':
    case 'tests':
        history.validateParameter(historyInstance.dashboardSpecificState, key, value,
            function() {
                return string.isValidName(value);
            });
        return true;

    case 'builder':
        history.validateParameter(historyInstance.dashboardSpecificState, key, value,
            function() {
                return value in currentBuilders();
            });

        return true;

    case 'sortColumn':
        history.validateParameter(historyInstance.dashboardSpecificState, key, value,
            function() {
                // Get all possible headers since the actual used set of headers
                // depends on the values in historyInstance.dashboardSpecificState, which are currently being set.
                var getAllTableHeaders = true;
                var headers = tableHeaders(getAllTableHeaders);
                for (var i = 0; i < headers.length; i++) {
                    if (value == sortColumnFromTableHeader(headers[i]))
                        return true;
                }
                return value == 'test' || value == 'builder';
            });
        return true;

    case 'sortOrder':
        history.validateParameter(historyInstance.dashboardSpecificState, key, value,
            function() {
                return value == FORWARD || value == BACKWARD;
            });
        return true;

    case 'resultsHeight':
    case 'revision':
        history.validateParameter(historyInstance.dashboardSpecificState, key, Number(value),
            function() {
                return value.match(/^\d+$/);
            });
        return true;

    case 'showChrome':
    case 'showExpectations':
    case 'showFlaky':
    case 'showLargeExpectations':
    case 'showNonFlaky':
    case 'showSlow':
    case 'showSkip':
    case 'showUnexpectedPasses':
    case 'showWontFix':
        historyInstance.dashboardSpecificState[key] = value == 'true';
        return true;

    default:
        return false;
    }
}

// @param {Object} params New or modified query parameters as key: value.
function handleQueryParameterChange(historyInstance, params)
{
    for (key in params) {
        if (key == 'tests') {
            // Entering cross-builder view, only keep valid keys for that view.
            for (var currentKey in historyInstance.dashboardSpecificState) {
              if (isInvalidKeyForCrossBuilderView(currentKey)) {
                delete historyInstance.dashboardSpecificState[currentKey];
              }
            }
        } else if (isInvalidKeyForCrossBuilderView(key)) {
            delete historyInstance.dashboardSpecificState.tests;
            delete historyInstance.dashboardSpecificState.result;
        }
    }

    return true;
}

var defaultDashboardSpecificStateValues = {
    sortOrder: BACKWARD,
    sortColumn: 'flakiness',
    showExpectations: false,
    // FIXME: Show flaky tests by default if you have a builder picked.
    // Ideally, we'd fix the dashboard to not pick a default builder and have
    // you pick one. In the interim, this is a good way to make the default
    // page load faster since we don't need to generate/layout a large table.
    showFlaky: false,
    showLargeExpectations: false,
    showChrome: true,
    showWontFix: false,
    showNonFlaky: false,
    showSkip: false,
    showUnexpectedPasses: false,
    resultsHeight: 300,
    revision: null,
    tests: '',
    result: '',
    builder: null
};

var DB_SPECIFIC_INVALIDATING_PARAMETERS = {
    'tests' : 'builder',
    'testType': 'builder',
    'group': 'builder'
};

var flakinessConfig = {
    defaultStateValues: defaultDashboardSpecificStateValues,
    generatePage: generatePage,
    handleValidHashParameter: handleValidHashParameter,
    handleQueryParameterChange: handleQueryParameterChange,
    invalidatingHashParameters: DB_SPECIFIC_INVALIDATING_PARAMETERS
};

// FIXME(jparent): Eventually remove all usage of global history object.
var g_history = new history.History(flakinessConfig);
g_history.parseCrossDashboardParameters();

//////////////////////////////////////////////////////////////////////////////
// GLOBALS
//////////////////////////////////////////////////////////////////////////////

var g_perBuilderFailures = {};
// Maps test path to an array of {builder, testResults} objects.
var g_testToResultsMap = {};

function createResultsObjectForTest(test, builder)
{
    return {
        test: test,
        builder: builder,
        // HTML for display of the results in the flakiness column
        html: '',
        flips: 0,
        slowestTime: 0,
        isFlaky: false,
        bugs: [],
        expectations : '',
        rawResults: '',
        // List of all the results the test actually has.
        actualResults: []
    };
}

var TestTrie = function(builders, resultsByBuilder)
{
    this._trie = {};

    for (var builder in builders) {
        if (!resultsByBuilder[builder]) {
            console.warn("No results for builder: ", builder)
            continue;
        }
        var testsForBuilder = resultsByBuilder[builder].tests;
        for (var test in testsForBuilder)
            this._addTest(test.split('/'), this._trie);
    }
}

TestTrie.prototype.forEach = function(callback, startingTriePath)
{
    var testsTrie = this._trie;
    if (startingTriePath) {
        var splitPath = startingTriePath.split('/');
        while (splitPath.length && testsTrie)
            testsTrie = testsTrie[splitPath.shift()];
    }

    if (!testsTrie)
        return;

    function traverse(trie, triePath) {
        if (trie == true)
            callback(triePath);
        else {
            for (var member in trie)
                traverse(trie[member], triePath ? triePath + '/' + member : member);
        }
    }
    traverse(testsTrie, startingTriePath);
}

TestTrie.prototype._addTest = function(test, trie)
{
    var rootComponent = test.shift();
    if (!test.length) {
        if (!trie[rootComponent])
            trie[rootComponent] = true;
        return;
    }

    if (!trie[rootComponent] || trie[rootComponent] == true)
        trie[rootComponent] = {};
    this._addTest(test, trie[rootComponent]);
}

// Map of all tests to true values. This is just so we can have the list of
// all tests across all the builders.
var g_allTestsTrie;

function getAllTestsTrie()
{
    if (!g_allTestsTrie)
        g_allTestsTrie = new TestTrie(currentBuilders(), g_resultsByBuilder);

    return g_allTestsTrie;
}

// Returns an array of tests to be displayed in the individual tests view.
// Note that a directory can be listed as a test, so we expand that into all
// tests in the directory.
function individualTests()
{
    if (g_history.dashboardSpecificState.result)
        return allTestsWithResult(g_history.dashboardSpecificState.result);

    if (!g_history.dashboardSpecificState.tests)
        return [];

    return individualTestsForSubstringList();
}

function splitTestList()
{
    // Convert windows slashes to unix slashes and spaces/newlines to commas.
    var tests = g_history.dashboardSpecificState.tests.replace(/\\/g, '/').replace('\n', ' ').replace(/\s+/g, ',');
    return tests.split(',');
}

function individualTestsForSubstringList()
{
    var testList = splitTestList();
    // If listing a lot of tests, assume you've passed in an explicit list of tests
    // instead of patterns to match against. The matching code below is super slow.
    //
    // Also, when showChrome is false, we're embedding the dashboard elsewhere and
    // an explicit test list is passed in. In that case, we don't want
    // a search for compositing/foo.html to also show virtual/softwarecompositing/foo.html.
    if (testList.length > 10 || !g_history.dashboardSpecificState.showChrome)
        return testList;

    // Put the tests into an object first and then move them into an array
    // as a way of deduping.
    var testsMap = {};
    for (var i = 0; i < testList.length; i++) {
        var path = testList[i];

        // Ignore whitespace entries as they'd match every test.
        if (path.match(/^\s*$/))
            continue;

        var hasAnyMatches = false;
        getAllTestsTrie().forEach(function(triePath) {
            if (string.caseInsensitiveContains(triePath, path)) {
                testsMap[triePath] = 1;
                hasAnyMatches = true;
            }
        });

        // If a path doesn't match any tests, then assume it's a full path
        // to a test that passes on all builders.
        if (!hasAnyMatches)
            testsMap[path] = 1;
    }

    var testsArray = [];
    for (var test in testsMap)
        testsArray.push(test);

    return testsArray;
}

function allTestsWithResult(result)
{
    processTestRunsForAllBuilders();
    var retVal = [];

    getAllTestsTrie().forEach(function(triePath) {
        for (var i = 0; i < g_testToResultsMap[triePath].length; i++) {
            if (g_testToResultsMap[triePath][i].actualResults.indexOf(result.toUpperCase()) != -1) {
                retVal.push(triePath);
                break;
            }
        }
    });

    return retVal;
}

function processTestResultsForBuilderAsync(builder)
{
    setTimeout(function() { processTestRunsForBuilder(builder); }, 0);
}

function processTestRunsForAllBuilders()
{
    for (var builder in currentBuilders())
        processTestRunsForBuilder(builder);
}

function processTestRunsForBuilder(builderName)
{
    if (g_perBuilderFailures[builderName])
      return;

    if (!g_resultsByBuilder[builderName]) {
        console.error('No tests found for ' + builderName);
        g_perBuilderFailures[builderName] = [];
        return;
    }

    var failures = [];
    var allTestsForThisBuilder = g_resultsByBuilder[builderName].tests;

    for (var test in allTestsForThisBuilder) {
        var resultsForTest = createResultsObjectForTest(test, builderName);

        var rawTest = g_resultsByBuilder[builderName].tests[test];
        resultsForTest.rawTimes = rawTest.times;
        var rawResults = rawTest.results;
        resultsForTest.rawResults = rawResults;

        if (rawTest.expected)
            resultsForTest.expectations = rawTest.expected;

        if (rawTest.bugs)
            resultsForTest.bugs = rawTest.bugs;

        var failureMap = g_resultsByBuilder[builderName][results.FAILURE_MAP];
        // FIXME: Switch to resultsByBuild
        var times = resultsForTest.rawTimes;
        var numTimesSeen = 0;
        var numResultsSeen = 0;
        var resultsIndex = 0;
        var resultsMap = {}

        for (var i = 0; i < times.length; i++) {
            numTimesSeen += times[i][results.RLE.LENGTH];

            while (rawResults[resultsIndex] && numTimesSeen > (numResultsSeen + rawResults[resultsIndex][results.RLE.LENGTH])) {
                numResultsSeen += rawResults[resultsIndex][results.RLE.LENGTH];
                resultsIndex++;
            }

            if (rawResults && rawResults[resultsIndex]) {
                var result = rawResults[resultsIndex][results.RLE.VALUE];
                resultsMap[failureMap[result]] = true;
            }

            resultsForTest.slowestTime = Math.max(resultsForTest.slowestTime, times[i][results.RLE.VALUE]);
        }

        resultsForTest.actualResults = Object.keys(resultsMap);

        results.determineFlakiness(failureMap, rawResults, resultsForTest);
        failures.push(resultsForTest);

        if (!g_testToResultsMap[test])
            g_testToResultsMap[test] = [];
        g_testToResultsMap[test].push(resultsForTest);
    }

    g_perBuilderFailures[builderName] = failures;
}

function linkHTMLToOpenWindow(url, text)
{
    return '<a href="' + url + '" target="_blank">' + text + '</a>';
}

// Returns whether the result for index'th result for testName on builder was
// a failure.
function isFailure(builder, testName, index)
{
    var currentIndex = 0;
    var rawResults = g_resultsByBuilder[builder].tests[testName].results;
    var failureMap = g_resultsByBuilder[builder][results.FAILURE_MAP];
    for (var i = 0; i < rawResults.length; i++) {
        currentIndex += rawResults[i][results.RLE.LENGTH];
        if (currentIndex > index)
            return results.isFailingResult(failureMap, rawResults[i][results.RLE.VALUE]);
    }
    console.error('Index exceeds number of results: ' + index);
}

// Returns an array of indexes for all builds where this test failed.
function indexesForFailures(builder, testName)
{
    var rawResults = g_resultsByBuilder[builder].tests[testName].results;
    var buildNumbers = g_resultsByBuilder[builder].buildNumbers;
    var failureMap = g_resultsByBuilder[builder][results.FAILURE_MAP];
    var index = 0;
    var failures = [];
    for (var i = 0; i < rawResults.length; i++) {
        var numResults = rawResults[i][results.RLE.LENGTH];
        if (results.isFailingResult(failureMap, rawResults[i][results.RLE.VALUE])) {
            for (var j = 0; j < numResults; j++)
                failures.push(index + j);
        }
        index += numResults;
    }
    return failures;
}

// Returns the path to the failure log for this non-webkit test.
function pathToFailureLog(testName)
{
    return '/steps/' + g_history.crossDashboardState.testType + '/logs/' + testName.split('.')[1]
}

function showPopupForBuild(e, builder, index, opt_testName)
{
    var html = '';

    var time = g_resultsByBuilder[builder].secondsSinceEpoch[index];
    if (time) {
        var date = new Date(time * 1000);
        html += date.toLocaleDateString() + ' ' + date.toLocaleTimeString();
    }

    var buildNumber = g_resultsByBuilder[builder].buildNumbers[index];
    var master = builders.master(builder);
    var buildBasePath = master.logPath(builder, buildNumber);

    html += '<ul><li>' + linkHTMLToOpenWindow(buildBasePath, 'Build log');

    if (g_resultsByBuilder[builder][results.BLINK_REVISIONS])
        html += '</li><li>Blink: ' + ui.html.blinkRevisionLink(g_resultsByBuilder[builder], index) + '</li>';

    html += '</li><li>Chromium: ' + ui.html.chromiumRevisionLink(g_resultsByBuilder[builder], index) + '</li>';

    var chromeRevision = g_resultsByBuilder[builder].chromeRevision[index];
    if (chromeRevision && g_history.isLayoutTestResults()) {
        html += '<li><a href="' + TEST_RESULTS_BASE_PATH + currentBuilders()[builder] +
            '/' + buildNumber + '/layout-test-results.zip">layout-test-results.zip</a></li>';
    }

    if (!g_history.isLayoutTestResults() && opt_testName && isFailure(builder, opt_testName, index))
        html += '<li>' + linkHTMLToOpenWindow(buildBasePath + pathToFailureLog(opt_testName), 'Failure log') + '</li>';

    html += '</ul>';
    ui.popup.show(e.target, html);
}

function classNameForFailureString(failure)
{
    return failure.replace(/(\+|\ )/, '');
}

function htmlForTestResults(test)
{
    var html = '';
    var testResults = test.rawResults.concat();
    var times = test.rawTimes.concat();
    var builder = test.builder;
    var master = builders.master(builder);
    var buildNumbers = g_resultsByBuilder[builder].buildNumbers;

    var indexToReplaceCurrentResult = -1;
    var indexToReplaceCurrentTime = -1;
    for (var i = 0; i < buildNumbers.length; i++) {
        var currentResultArray, currentTimeArray, innerHTML, resultString;

        if (i > indexToReplaceCurrentResult) {
            currentResultArray = testResults.shift();
            if (currentResultArray) {
                resultString = g_resultsByBuilder[builder][results.FAILURE_MAP][currentResultArray[results.RLE.VALUE]];
                indexToReplaceCurrentResult += currentResultArray[results.RLE.LENGTH];
            } else {
                resultString = results.NO_DATA;
                indexToReplaceCurrentResult += buildNumbers.length;
            }
        }

        if (i > indexToReplaceCurrentTime) {
            currentTimeArray = times.shift();
            var currentTime = 0;
            if (currentResultArray) {
              currentTime = currentTimeArray[results.RLE.VALUE];
              indexToReplaceCurrentTime += currentTimeArray[results.RLE.LENGTH];
            } else
              indexToReplaceCurrentTime += buildNumbers.length;

            innerHTML = currentTime || '&nbsp;';
        }

        html += '<td title="' + resultString + '. Click for more info." class="results ' + classNameForFailureString(resultString) +
          '" onclick=\'showPopupForBuild(event, "' + builder + '",' + i + ',"' + test.test + '")\'>' + innerHTML;
    }
    return html;
}

function shouldShowTest(testResult)
{
    if (!g_history.isLayoutTestResults())
        return true;

    if (testResult.expectations == 'WONTFIX')
        return g_history.dashboardSpecificState.showWontFix;

    if (testResult.expectations == results.SKIP)
        return g_history.dashboardSpecificState.showSkip;

    if (testResult.isFlaky)
        return g_history.dashboardSpecificState.showFlaky;

    return g_history.dashboardSpecificState.showNonFlaky;
}

function createBugHTML(test)
{
    var symptom = test.isFlaky ? 'flaky' : 'failing';
    var title = encodeURIComponent('Layout Test ' + test.test + ' is ' + symptom);
    var description = encodeURIComponent('The following layout test is ' + symptom + ' on ' +
        '[insert platform]\n\n' + test.test + '\n\nProbable cause:\n\n' +
        '[insert probable cause]');

    url = 'https://code.google.com/p/chromium/issues/entry?template=Layout%20Test%20Failure&summary=' + title + '&comment=' + description;
    return '<a href="' + url + '">File new bug</a>';
}

function isCrossBuilderView()
{
    return g_history.dashboardSpecificState.tests || g_history.dashboardSpecificState.result;
}

function tableHeaders(opt_getAll)
{
    var headers = [];
    if (isCrossBuilderView() || opt_getAll)
        headers.push('builder');

    if (!isCrossBuilderView() || opt_getAll)
        headers.push('test');

    if (g_history.isLayoutTestResults() || opt_getAll)
        headers.push('bugs', 'expectations');

    headers.push('slowest run', 'flakiness (numbers are runtimes in seconds)');
    return headers;
}

function linkifyBugs(bugs)
{
    var html = '';
    bugs.forEach(function(bug) {
        var bugHtml;
        if (string.startsWith(bug, 'Bug('))
            bugHtml = bug;
        else
            bugHtml = '<a href="http://' + bug + '">' + bug + '</a>';
        html += '<div>' + bugHtml + '</div>'
    });
    return html;
}

function htmlForSingleTestRow(test, showBuilderNames)
{
    var headers = tableHeaders();
    var html = '';
    for (var i = 0; i < headers.length; i++) {
        var header = headers[i];
        if (string.startsWith(header, 'test') || string.startsWith(header, 'builder')) {
            var testCellClassName = 'test-link' + (showBuilderNames ? ' builder-name' : '');
            var testCellHTML = showBuilderNames ? test.builder : '<span class="link" onclick="g_history.setQueryParameter(\'tests\',\'' + test.test +'\');">' + test.test + '</span>';
            html += '<tr><td class="' + testCellClassName + '">' + testCellHTML;
        } else if (string.startsWith(header, 'bugs'))
            // FIXME: linkify bugs.
            html += '<td class=options-container>' + (linkifyBugs(test.bugs) || createBugHTML(test));
        else if (string.startsWith(header, 'expectations'))
            html += '<td class=options-container>' + test.expectations;
        else if (string.startsWith(header, 'slowest'))
            html += '<td>' + (test.slowestTime ? test.slowestTime + 's' : '');
        else if (string.startsWith(header, 'flakiness'))
            html += htmlForTestResults(test);
    }
    return html;
}

function sortColumnFromTableHeader(headerText)
{
    return headerText.split(' ', 1)[0];
}

function htmlForTableColumnHeader(headerName, opt_fillColSpan)
{
    // Use the first word of the header title as the sortkey
    var thisSortValue = sortColumnFromTableHeader(headerName);
    var arrowHTML = thisSortValue == g_history.dashboardSpecificState.sortColumn ?
        '<span class=' + g_history.dashboardSpecificState.sortOrder + '>' + (g_history.dashboardSpecificState.sortOrder == FORWARD ? '&uarr;' : '&darr;' ) + '</span>' : '';
    return '<th sortValue=' + thisSortValue +
        // Extend last th through all the rest of the columns.
        (opt_fillColSpan ? ' colspan=10000' : '') +
        // Extra span here is so flex boxing actually centers.
        // There's probably a better way to do this with CSS only though.
        '><div class=table-header-content><span></span>' + arrowHTML +
        '<span class=header-text>' + headerName + '</span>' + arrowHTML + '</div></th>';
}

function htmlForTestTable(rowsHTML, opt_excludeHeaders)
{
    var html = '<table class=test-table>';
    if (!opt_excludeHeaders) {
        html += '<thead><tr>';
        var headers = tableHeaders();
        for (var i = 0; i < headers.length; i++)
            html += htmlForTableColumnHeader(headers[i], i == headers.length - 1);
        html += '</tr></thead>';
    }
    return html + '<tbody>' + rowsHTML + '</tbody></table>';
}

function appendHTML(html)
{
    // InnerHTML to a div that's not in the document. This is
    // ~300ms faster in Safari 4 and Chrome 4 on mac.
    var div = document.createElement('div');
    div.innerHTML = html;
    document.body.appendChild(div);
    postHeightChangedMessage();
}

function alphanumericCompare(column, reverse)
{
    return reversibleCompareFunction(function(a, b) {
        // Put null entries at the bottom
        var a = a[column] ? String(a[column]) : 'z';
        var b = b[column] ? String(b[column]) : 'z';

        if (a < b)
            return -1;
        else if (a == b)
            return 0;
        else
            return 1;
    }, reverse);
}

function numericSort(column, reverse)
{
    return reversibleCompareFunction(function(a, b) {
        a = parseFloat(a[column]);
        b = parseFloat(b[column]);
        return a - b;
    }, reverse);
}

function reversibleCompareFunction(compare, reverse)
{
    return function(a, b) {
        return compare(reverse ? b : a, reverse ? a : b);
    };
}

function changeSort(e)
{
    var target = e.currentTarget;
    e.preventDefault();

    var sortValue = target.getAttribute('sortValue');
    while (target && target.tagName != 'TABLE')
        target = target.parentNode;

    var sort = 'sortColumn';
    var orderKey = 'sortOrder';
    if (sortValue == g_history.dashboardSpecificState[sort] && g_history.dashboardSpecificState[orderKey] == FORWARD)
        order = BACKWARD;
    else
        order = FORWARD;

    g_history.setQueryParameter(sort, sortValue, orderKey, order);
}

function sortTests(tests, column, order)
{
    var resultsProperty, sortFunctionGetter;
    if (column == 'flakiness') {
        sortFunctionGetter = numericSort;
        resultsProperty = 'flips';
    } else if (column == 'slowest') {
        sortFunctionGetter = numericSort;
        resultsProperty = 'slowestTime';
    } else {
        sortFunctionGetter = alphanumericCompare;
        resultsProperty = column;
    }

    tests.sort(sortFunctionGetter(resultsProperty, order == BACKWARD));
}

function htmlForIndividualTestOnAllBuilders(test)
{
    processTestRunsForAllBuilders();

    var testResults = g_testToResultsMap[test];
    if (!testResults)
        return '<div class="not-found">Test not found. Either it does not exist, is skipped or passes on all recorded runs.</div>';

    var html = '';
    var shownBuilders = [];
    for (var j = 0; j < testResults.length; j++) {
        shownBuilders.push(testResults[j].builder);
        var showBuilderNames = true;
        html += htmlForSingleTestRow(testResults[j], showBuilderNames);
    }

    var skippedBuilders = []
    for (builder in currentBuilders()) {
        if (shownBuilders.indexOf(builder) == -1)
            skippedBuilders.push(builder);
    }

    var skippedBuildersHtml = '';
    if (skippedBuilders.length) {
        skippedBuildersHtml = '<div>The following builders either don\'t run this test (e.g. it\'s skipped) or all recorded runs passed:</div>' +
            '<div class=skipped-builder-list><div class=skipped-builder>' + skippedBuilders.join('</div><div class=skipped-builder>') + '</div></div>';
    }

    return htmlForTestTable(html) + skippedBuildersHtml;
}

function htmlForIndividualTestOnAllBuildersWithResultsLinks(test)
{
    processTestRunsForAllBuilders();

    var testResults = g_testToResultsMap[test];
    var html = '';
    html += htmlForIndividualTestOnAllBuilders(test);

    html += '<div class=expectations test=' + test + '><div>' +
        linkHTMLToToggleState('showExpectations', 'results')

    if (g_history.isLayoutTestResults() || g_history.isGPUTestResults()) {
        if (g_history.isLayoutTestResults())
            html += ' | ' + linkHTMLToToggleState('showLargeExpectations', 'large thumbnails');
            html += ' | <b>Only shows actual results/diffs from the most recent *failure* on each bot.</b>';
    } else {
      html += ' | <span>Results height:<input ' +
          'onchange="g_history.setQueryParameter(\'resultsHeight\',this.value)" value="' +
          g_history.dashboardSpecificState.resultsHeight + '" style="width:2.5em">px</span>';
    }
    html += '</div></div>';
    return html;
}

function maybeAddPngChecksum(expectationDiv, pngUrl)
{
    // pngUrl gets served from the browser cache since we just loaded it in an
    // <img> tag.
    loader.request(pngUrl,
        function(xhr) {
            // Convert the first 2k of the response to a byte string.
            var bytes = xhr.responseText.substring(0, 2048);
            for (var position = 0; position < bytes.length; ++position)
                bytes[position] = bytes[position] & 0xff;

            // Look for the comment.
            var commentKey = 'tEXtchecksum\x00';
            var checksumPosition = bytes.indexOf(commentKey);
            if (checksumPosition == -1)
                return;

            var checksum = bytes.substring(checksumPosition + commentKey.length, checksumPosition + commentKey.length + 32);
            var checksumContainer = document.createElement('span');
            checksumContainer.innerText = 'Embedded checksum: ' + checksum;
            checksumContainer.setAttribute('class', 'pngchecksum');
            expectationDiv.parentNode.appendChild(checksumContainer);
        },
        function(xhr) {},
        true);
}

function getOrCreate(className, parent)
{
    var element = parent.querySelector('.' + className);
    if (!element) {
        element = document.createElement('div');
        element.className = className;
        parent.appendChild(element);
    }
    return element;
}

function handleExpectationsItemLoad(title, item, itemType, parent)
{
    item.className = 'expectation';
    if (g_history.dashboardSpecificState.showLargeExpectations)
        item.className += ' large';

    var titleContainer = document.createElement('h3');
    titleContainer.className = 'expectations-title';
    titleContainer.textContent = title;

    var itemContainer = document.createElement('span');
    itemContainer.appendChild(titleContainer);
    itemContainer.className = 'expectations-item ' + title;
    itemContainer.appendChild(item);

    // Separate text and image results into separate divs..
    var typeContainer = getOrCreate(itemType, parent);

    // Insert results in a consistent order.
    var index = EXPECTATIONS_ORDER.indexOf(title);
    while (index < EXPECTATIONS_ORDER.length) {
        index++;
        var elementAfter = typeContainer.querySelector('.' + EXPECTATIONS_ORDER[index]);
        if (elementAfter) {
            typeContainer.insertBefore(itemContainer, elementAfter);
            break;
        }
    }
    if (!itemContainer.parentNode)
        typeContainer.appendChild(itemContainer);

    handleFinishedLoadingExpectations(parent);
}

function addExpectationItem(expectationsContainers, parentContainer, url, opt_builder)
{
    // Group expectations by builder, putting test and reference files first.
    var builder = opt_builder || "Test and reference files";
    var container = expectationsContainers[builder];

    if (!container) {
        container = document.createElement('div');
        container.className = 'expectations-container';
        container.setAttribute('data-builder', builder);
        parentContainer.appendChild(container);
        expectationsContainers[builder] = container;
    }

    var numUnloaded = container.getAttribute('data-unloaded') || 0;
    container.setAttribute('data-unloaded', ++numUnloaded);

    var isImage = url.match(/\.png$/);

    var appendExpectationsItem = function(item) {
        var itemType = isImage ? 'image' : 'text';
        handleExpectationsItemLoad(expectationsTitle(url), item, itemType, container);
    };

    var handleLoadError = function() {
        handleFinishedLoadingExpectations(container);
    };

    if (isImage) {
        var dummyNode = document.createElement('img');
        dummyNode.onload = function() {
            var item = dummyNode;
            maybeAddPngChecksum(item, url);
            appendExpectationsItem(item);
        }
        dummyNode.onerror = handleLoadError;
        dummyNode.src = url;
    } else {
        loader.request(url,
            function(xhr) {
                var item = document.createElement('pre');
                if (string.endsWith(url, '-wdiff.html'))
                    item.innerHTML = xhr.responseText;
                else
                    item.textContent = xhr.responseText;
                appendExpectationsItem(item);
            },
            handleLoadError);
    }
}

function handleFinishedLoadingExpectations(container)
{
    var numUnloaded = container.getAttribute('data-unloaded') - 1;
    container.setAttribute('data-unloaded', numUnloaded);
    if (numUnloaded)
        return;

    if (!container.firstChild) {
        container.remove();
        return;
    }

    var builder = container.getAttribute('data-builder');
    if (!builder)
        return;

    var header = document.createElement('h2');
    header.textContent = builder;
    container.insertBefore(header, container.firstChild);
}

function expectationsTitle(url)
{
    var matchingSuffixes = ACTUAL_RESULT_SUFFIXES.filter(function(suffix) {
        return string.endsWith(url, suffix);
    });

    if (matchingSuffixes.length)
        return matchingSuffixes[0].split('.')[0];

    var parts = url.split('/');
    return parts[parts.length - 1];
}

function loadExpectations(expectationsContainer)
{
    var test = expectationsContainer.getAttribute('test');
    if (g_history.isLayoutTestResults())
        loadExpectationsLayoutTests(test, expectationsContainer);
    else {
        var testResults = g_testToResultsMap[test];
        for (var i = 0; i < testResults.length; i++)
            if (g_history.isGPUTestResults())
                loadGPUResultsForBuilder(testResults[i].builder, test, expectationsContainer);
            else
                loadNonWebKitResultsForBuilder(testResults[i].builder, test, expectationsContainer);
    }
}

function gpuResultsPath(chromeRevision, builder)
{
  return chromeRevision + '_' + builder.replace(/[^A-Za-z0-9]+/g, '_');
}

function loadGPUResultsForBuilder(builder, test, expectationsContainer)
{
    var container = document.createElement('div');
    container.className = 'expectations-container';
    container.innerHTML = '<div><b>' + builder + '</b></div>';
    expectationsContainer.appendChild(container);

    var failureIndex = indexesForFailures(builder, test)[0];

    var buildNumber = g_resultsByBuilder[builder].buildNumbers[failureIndex];
    var pathToLog = builders.master(builder).logPath(builder, buildNumber) + pathToFailureLog(test);

    var chromeRevision = g_resultsByBuilder[builder].chromeRevision[failureIndex];
    var resultsUrl = GPU_RESULTS_BASE_PATH + gpuResultsPath(chromeRevision, builder);
    var filename = test.split(/\./)[1] + '.png';

    appendNonWebKitResults(container, pathToLog, 'non-webkit-results');
    appendNonWebKitResults(container, resultsUrl + '/gen/' + filename, 'gpu-test-results', 'Generated');
    appendNonWebKitResults(container, resultsUrl + '/ref/' + filename, 'gpu-test-results', 'Reference');
    appendNonWebKitResults(container, resultsUrl + '/diff/' + filename, 'gpu-test-results', 'Diff');
}

function loadNonWebKitResultsForBuilder(builder, test, expectationsContainer)
{
    var failureIndexes = indexesForFailures(builder, test);
    var container = document.createElement('div');
    container.innerHTML = '<div><b>' + builder + '</b></div>';
    expectationsContainer.appendChild(container);
    for (var i = 0; i < failureIndexes.length; i++) {
        // FIXME: This doesn't seem to work anymore. Did the paths change?
        // Once that's resolved, see if we need to try each gtest modifier prefix as well.
        var buildNumber = g_resultsByBuilder[builder].buildNumbers[failureIndexes[i]];
        var pathToLog = builders.master(builder).logPath(builder, buildNumber) + pathToFailureLog(test);
        appendNonWebKitResults(container, pathToLog, 'non-webkit-results');
    }
}

function appendNonWebKitResults(container, url, itemClassName, opt_title)
{
    // Use a script tag to detect whether the URL 404s.
    // Need to use a script tag since the URL is cross-domain.
    var dummyNode = document.createElement('script');
    dummyNode.src = url;

    dummyNode.onload = function() {
        var item = document.createElement('iframe');
        item.src = dummyNode.src;
        item.className = itemClassName;
        item.style.height = g_history.dashboardSpecificState.resultsHeight + 'px';

        if (opt_title) {
            var childContainer = document.createElement('div');
            childContainer.style.display = 'inline-block';
            var title = document.createElement('div');
            title.textContent = opt_title;
            childContainer.appendChild(title);
            childContainer.appendChild(item);
            container.replaceChild(childContainer, dummyNode);
        } else
            container.replaceChild(item, dummyNode);
    }
    dummyNode.onerror = function() {
        container.removeChild(dummyNode);
    }

    container.appendChild(dummyNode);
}

function lookupVirtualTestSuite(test) {
    for (var suite in VIRTUAL_SUITES) {
        if (test.indexOf(suite) != -1)
            return suite;
    }
    return '';
}

function baseTest(test, suite) {
    base = VIRTUAL_SUITES[suite];
    return base ? test.replace(suite, base) : test;
}

function loadTestAndReferenceFiles(expectationsContainers, expectationsContainer, test) {
    var testWithoutSuffix = test.substring(0, test.lastIndexOf('.'));
    var reftest_html_file = testWithoutSuffix + "-expected.html";
    var reftest_mismatch_html_file = testWithoutSuffix + "-expected-mismatch.html";

    var suite = lookupVirtualTestSuite(test);
    if (suite) {
        loadTestAndReferenceFiles(expectationsContainers, expectationsContainer, baseTest(test, suite));
        return;
    }

    addExpectationItem(expectationsContainers, expectationsContainer, TEST_URL_BASE_PATH_FOR_XHR + test);
    addExpectationItem(expectationsContainers, expectationsContainer, TEST_URL_BASE_PATH_FOR_XHR + reftest_html_file);
    addExpectationItem(expectationsContainers, expectationsContainer, TEST_URL_BASE_PATH_FOR_XHR + reftest_mismatch_html_file);
}

function loadExpectationsLayoutTests(test, expectationsContainer)
{
    // Map from file extension to container div for expectations of that type.
    var expectationsContainers = {};
    loadTestAndReferenceFiles(expectationsContainers, expectationsContainer, test);

    var testWithoutSuffix = test.substring(0, test.lastIndexOf('.'));

    for (var builder in currentBuilders()) {
        var actualResultsBase = TEST_RESULTS_BASE_PATH + currentBuilders()[builder] + '/results/layout-test-results/';
        ACTUAL_RESULT_SUFFIXES.forEach(function(suffix) {{
            addExpectationItem(expectationsContainers, expectationsContainer, actualResultsBase + testWithoutSuffix + '-' + suffix, builder);
        }})
    }

    // Add a clearing element so floated elements don't bleed out of their
    // containing block.
    var br = document.createElement('br');
    br.style.clear = 'both';
    expectationsContainer.appendChild(br);
}

function appendExpectations()
{
    var expectations = g_history.dashboardSpecificState.showExpectations ? document.getElementsByClassName('expectations') : [];
    g_chunkedActionState = {
        items: expectations,
        index: 0
    }
    performChunkedAction(function(expectation) {
            loadExpectations(expectation);
            postHeightChangedMessage();
        },
        hideLoadingUI,
        expectations);
}

function hideLoadingUI()
{
    var loadingDiv = $('loading-ui');
    if (loadingDiv)
        loadingDiv.style.display = 'none';
    postHeightChangedMessage();
}

function generatePageForIndividualTests(tests)
{
    console.log('Number of tests: ' + tests.length);
    if (g_history.dashboardSpecificState.showChrome)
        appendHTML(htmlForNavBar());
    performChunkedAction(function(test) {
            appendHTML(htmlForIndividualTest(test));
        },
        appendExpectations,
        tests);
    if (g_history.dashboardSpecificState.showChrome) {
        $('tests-input').value = g_history.dashboardSpecificState.tests;
        $('result-input').value = g_history.dashboardSpecificState.result;
    }
}

var g_chunkedActionRequestId;
function performChunkedAction(action, onComplete, items, opt_index) {
    if (g_chunkedActionRequestId)
        cancelAnimationFrame(g_chunkedActionRequestId);

    var index = opt_index || 0;
    g_chunkedActionRequestId = requestAnimationFrame(function() {
        if (index < items.length) {
            action(items[index]);
            performChunkedAction(action, onComplete, items, ++index);
        } else {
            onComplete();
        }
    });
}

function htmlForIndividualTest(test)
{
    var testNameHtml = '';
    if (g_history.dashboardSpecificState.showChrome) {
        if (g_history.isLayoutTestResults()) {
            var suite = lookupVirtualTestSuite(test);
            var base = suite ? baseTest(test, suite) : test;
            var versionControlUrl = TEST_URL_BASE_PATH_FOR_BROWSING + base;
            testNameHtml += '<h2>' + linkHTMLToOpenWindow(versionControlUrl, test) + '</h2>';
        } else
            testNameHtml += '<h2>' + test + '</h2>';
    }

    return testNameHtml + htmlForIndividualTestOnAllBuildersWithResultsLinks(test);
}

function setTestsParameter(input)
{
    g_history.setQueryParameter('tests', input.value);
}

function htmlForNavBar()
{
    var extraHTML = '';
    var html = ui.html.testTypeSwitcher(false, extraHTML, isCrossBuilderView());
    html += '<div class=forms><form id=result-form ' +
        'onsubmit="g_history.setQueryParameter(\'result\', result.value);' +
        'return false;">Show all tests with result: ' +
        '<input name=result placeholder="e.g. CRASH" id=result-input>' +
        '</form><span>Show tests on all platforms: </span>' +
        // Use a textarea to avoid the 32k limit on the length of inputs.
        '<textarea name=tests ' +
        'placeholder="Comma or space-separated list of tests or partial ' +
        'paths to show test results across all builders, e.g., ' +
        'foo/bar.html,foo/baz,domstorage" id=tests-input onchange="setTestsParameter(this)" ' +
        'onkeydown="if (event.keyCode == 13) { setTestsParameter(this); return false; }"></textarea>' +
        '<span class=link onclick="showLegend()">Show legend [type ?]</span></div>';
    return html;
}

function checkBoxToToggleState(key, text)
{
    var stateEnabled = g_history.dashboardSpecificState[key];
    return '<label><input type=checkbox ' + (stateEnabled ? 'checked ' : '') + 'onclick="g_history.setQueryParameter(\'' + key + '\', ' + !stateEnabled + ')">' + text + '</label> ';
}

function linkHTMLToToggleState(key, linkText)
{
    var stateEnabled = g_history.dashboardSpecificState[key];
    return '<span class=link onclick="g_history.setQueryParameter(\'' + key + '\', ' + !stateEnabled + ')">' + (stateEnabled ? 'Hide' : 'Show') + ' ' + linkText + '</span>';
}

function headerForTestTableHtml()
{
    return '<h2 style="display:inline-block">Failing tests</h2>' +
        checkBoxToToggleState('showFlaky', 'Show flaky') +
        checkBoxToToggleState('showNonFlaky', 'Show non-flaky') +
        checkBoxToToggleState('showSkip', 'Show Skip') +
        checkBoxToToggleState('showWontFix', 'Show WontFix');
}

function generatePageForBuilder(builderName)
{
    processTestRunsForBuilder(builderName);

    var filteredResults = g_perBuilderFailures[builderName].filter(shouldShowTest);
    sortTests(filteredResults, g_history.dashboardSpecificState.sortColumn, g_history.dashboardSpecificState.sortOrder);

    var testsHTML = '';
    if (filteredResults.length) {
        var tableRowsHTML = '';
        var showBuilderNames = false;
        for (var i = 0; i < filteredResults.length; i++)
            tableRowsHTML += htmlForSingleTestRow(filteredResults[i], showBuilderNames)
        testsHTML = htmlForTestTable(tableRowsHTML);
    } else {
        if (g_history.isLayoutTestResults())
            testsHTML += '<div>Fill in one of the text inputs or checkboxes above to show failures.</div>';
        else
            testsHTML += '<div>No tests have failed!</div>';
    }

    var html = htmlForNavBar();

    if (g_history.isLayoutTestResults())
        html += headerForTestTableHtml();

    html += '<br>' + testsHTML;
    appendHTML(html);

    var ths = document.getElementsByTagName('th');
    for (var i = 0; i < ths.length; i++) {
        ths[i].addEventListener('click', changeSort, false);
        ths[i].className = "sortable";
    }

    hideLoadingUI();
}

var VALID_KEYS_FOR_CROSS_BUILDER_VIEW = {
    tests: 1,
    result: 1,
    showChrome: 1,
    showExpectations: 1,
    showLargeExpectations: 1,
    resultsHeight: 1,
    revision: 1
};

function isInvalidKeyForCrossBuilderView(key)
{
    return !(key in VALID_KEYS_FOR_CROSS_BUILDER_VIEW) && !(key in history.DEFAULT_CROSS_DASHBOARD_STATE_VALUES);
}

function hideLegend()
{
    var legend = $('legend');
    if (legend)
        legend.parentNode.removeChild(legend);
}

function showLegend()
{
    var legend = $('legend');
    if (!legend) {
        legend = document.createElement('div');
        legend.id = 'legend';
        document.body.appendChild(legend);
    }

    var html = '<div id=legend-toggle onclick="hideLegend()">Hide ' +
        'legend [type esc]</div><div id=legend-contents>';

    // Just grab the first failureMap. Technically, different builders can have different maps if they
    // haven't all cycled after the map was changed, but meh.
    var failureMap = g_resultsByBuilder[Object.keys(g_resultsByBuilder)[0]][results.FAILURE_MAP];
    for (var expectation in failureMap) {
        var failureString = failureMap[expectation];
        html += '<div class=' + classNameForFailureString(failureString) + '>' + failureString + '</div>';
    }

    if (g_history.isLayoutTestResults()) {
      html += '</div><br style="clear:both">' +
          '</div>';

      html += '<div>RELEASE TIMEOUTS:</div>' +
          htmlForSlowTimes(RELEASE_TIMEOUT) +
          '<div>DEBUG TIMEOUTS:</div>' +
          htmlForSlowTimes(DEBUG_TIMEOUT);
    }

    legend.innerHTML = html;
}

function htmlForSlowTimes(minTime)
{
    return '<ul><li>' + minTime + ' seconds</li><li>' +
        SLOW_MULTIPLIER * minTime + ' seconds if marked Slow in TestExpectations</li></ul>';
}

function postHeightChangedMessage()
{
    if (window == parent)
        return;

    var root = document.documentElement;
    var height = root.offsetHeight;
    if (root.offsetWidth < root.scrollWidth) {
        // We have a horizontal scrollbar. Include it in the height.
        var dummyNode = document.createElement('div');
        dummyNode.style.overflow = 'scroll';
        document.body.appendChild(dummyNode);
        var scrollbarWidth = dummyNode.offsetHeight - dummyNode.clientHeight;
        document.body.removeChild(dummyNode);
        height += scrollbarWidth;
    }
    parent.postMessage({command: 'heightChanged', height: height}, '*')
}

if (window != parent)
    window.addEventListener('blur', ui.popup.hide);

document.addEventListener('keydown', function(e) {
    if (e.keyIdentifier == 'U+003F' || e.keyIdentifier == 'U+00BF') {
        // WebKit MAC retursn 3F. WebKit WIN returns BF. This is a bug!
        // ? key
        showLegend();
    } else if (e.keyIdentifier == 'U+001B') {
        // escape key
        hideLegend();
        ui.popup.hide();
    }
}, false);

window.addEventListener('load', function() {
    resourceLoader = new loader.Loader();
    resourceLoader.load();
}, false);
