/*global add_completion_callback, setup */
/*
 * This file is intended for vendors to implement
 * code needed to integrate testharness.js tests with their own test systems.
 *
 * The default implementation extracts metadata from the tests and validates
 * it against the cached version that should be present in the test source
 * file. If the cache is not found or is out of sync, source code suitable for
 * caching the metadata is optionally generated.
 *
 * The cached metadata is present for extraction by test processing tools that
 * are unable to execute javascript.
 *
 * Metadata is attached to tests via the properties parameter in the test
 * constructor. See testharness.js for details.
 *
 * Typically test system integration will attach callbacks when each test has
 * run, using add_result_callback(callback(test)), or when the whole test file
 * has completed, using
 * add_completion_callback(callback(tests, harness_status)).
 *
 * For more documentation about the callback functions and the
 * parameters they are called with see testharness.js
 */



var metadata_generator = {

    currentMetadata: {},
    cachedMetadata: false,
    metadataProperties: ['help', 'assert', 'author'],

    error: function(message) {
        var messageElement = document.createElement('p');
        messageElement.setAttribute('class', 'error');
        this.appendText(messageElement, message);

        var summary = document.getElementById('summary');
        if (summary) {
            summary.parentNode.insertBefore(messageElement, summary);
        }
        else {
            document.body.appendChild(messageElement);
        }
    },

    /**
     * Ensure property value has contact information
     */
    validateContact: function(test, propertyName) {
        var result = true;
        var value = test.properties[propertyName];
        var values = Array.isArray(value) ? value : [value];
        for (var index = 0; index < values.length; index++) {
            value = values[index];
            var re = /(\S+)(\s*)<(.*)>(.*)/;
            if (! re.test(value)) {
                re = /(\S+)(\s+)(http[s]?:\/\/)(.*)/;
                if (! re.test(value)) {
                    this.error('Metadata property "' + propertyName +
                        '" for test: "' + test.name +
                        '" must have name and contact information ' +
                        '("name <email>" or "name http(s)://")');
                    result = false;
                }
            }
        }
        return result;
    },

    /**
     * Extract metadata from test object
     */
    extractFromTest: function(test) {
        var testMetadata = {};
        // filter out metadata from other properties in test
        for (var metaIndex = 0; metaIndex < this.metadataProperties.length;
             metaIndex++) {
            var meta = this.metadataProperties[metaIndex];
            if (test.properties.hasOwnProperty(meta)) {
                if ('author' == meta) {
                    this.validateContact(test, meta);
                }
                testMetadata[meta] = test.properties[meta];
            }
        }
        return testMetadata;
    },

    /**
     * Compare cached metadata to extracted metadata
     */
    validateCache: function() {
        for (var testName in this.currentMetadata) {
            if (! this.cachedMetadata.hasOwnProperty(testName)) {
                return false;
            }
            var testMetadata = this.currentMetadata[testName];
            var cachedTestMetadata = this.cachedMetadata[testName];
            delete this.cachedMetadata[testName];

            for (var metaIndex = 0; metaIndex < this.metadataProperties.length;
                 metaIndex++) {
                var meta = this.metadataProperties[metaIndex];
                if (cachedTestMetadata.hasOwnProperty(meta) &&
                    testMetadata.hasOwnProperty(meta)) {
                    if (Array.isArray(cachedTestMetadata[meta])) {
                      if (! Array.isArray(testMetadata[meta])) {
                          return false;
                      }
                      if (cachedTestMetadata[meta].length ==
                          testMetadata[meta].length) {
                          for (var index = 0;
                               index < cachedTestMetadata[meta].length;
                               index++) {
                              if (cachedTestMetadata[meta][index] !=
                                  testMetadata[meta][index]) {
                                  return false;
                              }
                          }
                      }
                      else {
                          return false;
                      }
                    }
                    else {
                      if (Array.isArray(testMetadata[meta])) {
                        return false;
                      }
                      if (cachedTestMetadata[meta] != testMetadata[meta]) {
                        return false;
                      }
                    }
                }
                else if (cachedTestMetadata.hasOwnProperty(meta) ||
                         testMetadata.hasOwnProperty(meta)) {
                    return false;
                }
            }
        }
        for (var testName in this.cachedMetadata) {
            return false;
        }
        return true;
    },

    appendText: function(elemement, text) {
        elemement.appendChild(document.createTextNode(text));
    },

    jsonifyArray: function(arrayValue, indent) {
        var output = '[';

        if (1 == arrayValue.length) {
            output += JSON.stringify(arrayValue[0]);
        }
        else {
            for (var index = 0; index < arrayValue.length; index++) {
                if (0 < index) {
                    output += ',\n  ' + indent;
                }
                output += JSON.stringify(arrayValue[index]);
            }
        }
        output += ']';
        return output;
    },

    jsonifyObject: function(objectValue, indent) {
        var output = '{';
        var value;

        var count = 0;
        for (var property in objectValue) {
            ++count;
            if (Array.isArray(objectValue[property]) ||
                ('object' == typeof(value))) {
                ++count;
            }
        }
        if (1 == count) {
            for (var property in objectValue) {
                output += ' "' + property + '": ' +
                    JSON.stringify(objectValue[property]) +
                    ' ';
            }
        }
        else {
            var first = true;
            for (var property in objectValue) {
                if (! first) {
                    output += ',';
                }
                first = false;
                output += '\n  ' + indent + '"' + property + '": ';
                value = objectValue[property];
                if (Array.isArray(value)) {
                    output += this.jsonifyArray(value, indent +
                        '                '.substr(0, 5 + property.length));
                }
                else if ('object' == typeof(value)) {
                    output += this.jsonifyObject(value, indent + '  ');
                }
                else {
                    output += JSON.stringify(value);
                }
            }
            if (1 < output.length) {
                output += '\n' + indent;
            }
        }
        output += '}';
        return output;
    },

    /**
     * Generate javascript source code for captured metadata
     * Metadata is in pretty-printed JSON format
     */
    generateSource: function() {
        /* "\/" is used instead of a plain forward slash so that the contents
        of testharnessreport.js can (for convenience) be copy-pasted into a
        script tag without issue. Otherwise, the HTML parser would think that
        the script ended in the middle of that string literal. */
        var source =
            '<script id="metadata_cache">/*\n' +
            this.jsonifyObject(this.currentMetadata, '') + '\n' +
            '*/<\/script>\n';
        return source;
    },

    /**
     * Add element containing metadata source code
     */
    addSourceElement: function(event) {
        var sourceWrapper = document.createElement('div');
        sourceWrapper.setAttribute('id', 'metadata_source');

        var instructions = document.createElement('p');
        if (this.cachedMetadata) {
            this.appendText(instructions,
                'Replace the existing <script id="metadata_cache"> element ' +
                'in the test\'s <head> with the following:');
        }
        else {
            this.appendText(instructions,
                'Copy the following into the <head> element of the test ' +
                'or the test\'s metadata sidecar file:');
        }
        sourceWrapper.appendChild(instructions);

        var sourceElement = document.createElement('pre');
        this.appendText(sourceElement, this.generateSource());

        sourceWrapper.appendChild(sourceElement);

        var messageElement = document.getElementById('metadata_issue');
        messageElement.parentNode.insertBefore(sourceWrapper,
                                               messageElement.nextSibling);
        messageElement.parentNode.removeChild(messageElement);

        (event.preventDefault) ? event.preventDefault() :
                                 event.returnValue = false;
    },

    /**
     * Extract the metadata cache from the cache element if present
     */
    getCachedMetadata: function() {
        var cacheElement = document.getElementById('metadata_cache');

        if (cacheElement) {
            var cacheText = cacheElement.firstChild.nodeValue;
            var openBrace = cacheText.indexOf('{');
            var closeBrace = cacheText.lastIndexOf('}');
            if ((-1 < openBrace) && (-1 < closeBrace)) {
                cacheText = cacheText.slice(openBrace, closeBrace + 1);
                try {
                    this.cachedMetadata = JSON.parse(cacheText);
                }
                catch (exc) {
                    this.cachedMetadata = 'Invalid JSON in Cached metadata. ';
                }
            }
            else {
                this.cachedMetadata = 'Metadata not found in cache element. ';
            }
        }
    },

    /**
     * Main entry point, extract metadata from tests, compare to cached version
     * if present.
     * If cache not present or differs from extrated metadata, generate an error
     */
    process: function(tests) {
        for (var index = 0; index < tests.length; index++) {
            var test = tests[index];
            if (this.currentMetadata.hasOwnProperty(test.name)) {
                this.error('Duplicate test name: ' + test.name);
            }
            else {
                this.currentMetadata[test.name] = this.extractFromTest(test);
            }
        }

        this.getCachedMetadata();

        var message = null;
        var messageClass = 'warning';
        var showSource = false;

        if (0 === tests.length) {
            if (this.cachedMetadata) {
                message = 'Cached metadata present but no tests. ';
            }
        }
        else if (1 === tests.length) {
            if (this.cachedMetadata) {
                message = 'Single test files should not have cached metadata. ';
            }
            else {
                var testMetadata = this.currentMetadata[tests[0].name];
                for (var meta in testMetadata) {
                    if (testMetadata.hasOwnProperty(meta)) {
                        message = 'Single tests should not have metadata. ' +
                                  'Move metadata to <head>. ';
                        break;
                    }
                }
            }
        }
        else {
            if (this.cachedMetadata) {
                messageClass = 'error';
                if ('string' == typeof(this.cachedMetadata)) {
                    message = this.cachedMetadata;
                    showSource = true;
                }
                else if (! this.validateCache()) {
                    message = 'Cached metadata out of sync. ';
                    showSource = true;
                }
            }
        }

        if (message) {
            var messageElement = document.createElement('p');
            messageElement.setAttribute('id', 'metadata_issue');
            messageElement.setAttribute('class', messageClass);
            this.appendText(messageElement, message);

            if (showSource) {
                var link = document.createElement('a');
                this.appendText(link, 'Click for source code.');
                link.setAttribute('href', '#');
                link.setAttribute('onclick',
                                  'metadata_generator.addSourceElement(event)');
                messageElement.appendChild(link);
            }

            var summary = document.getElementById('summary');
            if (summary) {
                summary.parentNode.insertBefore(messageElement, summary);
            }
            else {
                var log = document.getElementById('log');
                if (log) {
                    log.appendChild(messageElement);
                }
            }
        }
    },

    setup: function() {
        add_start_callback(
            function (properties) {
                if (window.testRunner) {
                    window.testRunner.waitUntilDone();
                }
            });
        add_completion_callback(
            function (tests, harness_status) {
                metadata_generator.process(tests, harness_status);
                dump_test_results(tests, harness_status);
            });
    }
};

function dump_test_results(tests, status) {
    var results_element = document.createElement("script");
    results_element.type = "text/json";
    results_element.id = "__testharness__results__";
    var test_results = tests.map(function(x) {
        return {name:x.name, status:x.status, message:x.message, stack:x.stack}
    });
    data = {test:window.location.href,
            tests:test_results,
            status: status.status,
            message: status.message,
            stack: status.stack};
    results_element.textContent = JSON.stringify(data);
    document.documentElement.lastChild.appendChild(results_element);
    if (window.testRunner) {
        window.testRunner.notifyDone();
        window.close();
    }
}

metadata_generator.setup();

/* If the parent window has a testharness_properties object,
 * we use this to provide the test settings. This is used by the
 * default in-browser runner to configure the timeout and the
 * rendering of results
 */
try {
    if (window.opener && "testharness_properties" in window.opener) {
        /* If we pass the testharness_properties object as-is here without
         * JSON stringifying and reparsing it, IE fails & emits the message
         * "Could not complete the operation due to error 80700019".
         */
        setup(JSON.parse(JSON.stringify(window.opener.testharness_properties)));
    }
} catch (e) {
}
// vim: set expandtab shiftwidth=4 tabstop=4:
