/*
 * Copyright (C) 2011 Google Inc.  All rights reserved.
 * Copyright (C) 2007, 2008, 2013 Apple Inc.  All rights reserved.
 * Copyright (C) 2008 Matt Lilek <webkit@mattlilek.com>
 * Copyright (C) 2009 Joseph Pecoraro
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1.  Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 * 2.  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.
 * 3.  Neither the name of Apple Inc. ("Apple") 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 APPLE AND ITS 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 APPLE OR ITS 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.
 */

WI.roleSelectorForNode = function(node)
{
    // This is proposed syntax for CSS 4 computed role selector :role(foo) and subject to change.
    // See http://lists.w3.org/Archives/Public/www-style/2013Jul/0104.html
    var title = "";
    var role = node.computedRole();
    if (role)
        title = ":role(" + role + ")";
    return title;
};

WI.linkifyAccessibilityNodeReference = function(node)
{
    if (!node)
        return null;
    // Same as linkifyNodeReference except the link text has the classnames removed...
    // ...for list brevity, and both text and title have roleSelectorForNode appended.
    var link = WI.linkifyNodeReference(node);
    var tagIdSelector = link.title;
    var classSelectorIndex = tagIdSelector.indexOf(".");
    if (classSelectorIndex > -1)
        tagIdSelector = tagIdSelector.substring(0, classSelectorIndex);
    var roleSelector = WI.roleSelectorForNode(node);
    link.textContent = tagIdSelector + roleSelector;
    link.title += roleSelector;
    return link;
};

WI.linkifyStyleable = function(styleable)
{
    console.assert(styleable instanceof WI.DOMStyleable, styleable);
    let displayName = styleable.displayName;
    let link = document.createElement("span");
    link.append(displayName);
    return WI.linkifyNodeReferenceElement(styleable.node, link, {displayName});
};

WI.linkifyNodeReference = function(node, options = {})
{
    let displayName = node.displayName;
    if (!isNaN(options.maxLength))
        displayName = displayName.truncate(options.maxLength);

    let link = document.createElement("span");
    link.append(displayName);
    return WI.linkifyNodeReferenceElement(node, link, {...options, displayName});
};

WI.linkifyNodeReferenceElement = function(node, element, options = {})
{
    element.setAttribute("role", "link");
    element.title = options.displayName || node.displayName;

    let nodeType = node.nodeType();
    if (!options.ignoreClick && (nodeType !== Node.DOCUMENT_NODE || node.parentNode) && nodeType !== Node.TEXT_NODE)
        element.classList.add("node-link");

    WI.bindInteractionsForNodeToElement(node, element, options);

    return element;
};

WI.bindInteractionsForNodeToElement = function(node, element, options = {}) {
    if (!options.ignoreClick) {
        element.addEventListener("click", (event) => {
            WI.domManager.inspectElement(node.id, {
                initiatorHint: WI.TabBrowser.TabNavigationInitiator.LinkClick,
            });
        });
    }

    element.addEventListener("mouseover", (event) => {
        node.highlight();
    });

    element.addEventListener("mouseout", (event) => {
        WI.domManager.hideDOMNodeHighlight();
    });

    element.addEventListener("contextmenu", (event) => {
        let contextMenu = WI.ContextMenu.createFromEvent(event);
        WI.appendContextMenuItemsForDOMNode(contextMenu, node, options);
    });
};

function createSVGElement(tagName)
{
    return document.createElementNS("http://www.w3.org/2000/svg", tagName);
}

WI.cssPath = function(node, options = {})
{
    console.assert(node instanceof WI.DOMNode, "Expected a DOMNode.");
    if (node.nodeType() !== Node.ELEMENT_NODE)
        return "";

    let suffix = "";
    if (node.isPseudoElement()) {
        suffix = "::" + node.pseudoType();
        node = node.parentNode;
    }

    let components = [];
    while (node) {
        let component = WI.cssPathComponent(node, options);
        if (!component)
            break;
        components.push(component);
        if (component.done)
            break;
        node = node.parentNode;
    }

    components.reverse();
    return components.map((x) => x.value).join(" > ") + suffix;
};

WI.cssPathComponent = function(node, options = {})
{
    console.assert(node instanceof WI.DOMNode, "Expected a DOMNode.");
    console.assert(!node.isPseudoElement());
    if (node.nodeType() !== Node.ELEMENT_NODE)
        return null;

    let nodeName = node.nodeNameInCorrectCase();

    // Root node does not have siblings.
    if (!node.parentNode || node.parentNode.nodeType() === Node.DOCUMENT_NODE)
        return {value: nodeName, done: true};

    if (options.full) {
        function getUniqueAttributes(domNode) {
            let uniqueAttributes = new Map;
            for (let attribute of domNode.attributes()) {
                let values = [attribute.value];
                if (attribute.name === "id" || attribute.name === "class")
                    values = attribute.value.split(/\s+/);
                uniqueAttributes.set(attribute.name, new Set(values));
            }
            return uniqueAttributes;
        }

        let nodeIndex = 0;
        let needsNthChild = false;
        let uniqueAttributes = getUniqueAttributes(node);
        node.parentNode.children.forEach((child, i) => {
            if (child.nodeType() !== Node.ELEMENT_NODE)
                return;

            if (child === node) {
                nodeIndex = i;
                return;
            }

            if (needsNthChild || child.nodeNameInCorrectCase() !== nodeName)
                return;

            let childUniqueAttributes = getUniqueAttributes(child);
            let subsetCount = 0;
            for (let [name, values] of uniqueAttributes) {
                let childValues = childUniqueAttributes.get(name);
                if (childValues && values.size <= childValues.size && values.isSubsetOf(childValues))
                    ++subsetCount;
            }

            if (subsetCount === uniqueAttributes.size)
                needsNthChild = true;
        });

        function selectorForAttribute(values, prefix = "", shouldCSSEscape = false) {
            if (!values || !values.size)
                return "";
            values = Array.from(values);
            values = values.filter((value) => value && value.length);
            if (!values.length)
                return "";
            values = values.map((value) => shouldCSSEscape ? CSS.escape(value) : value.escapeCharacters("\""));
            return prefix + values.join(prefix);
        }

        let selector = nodeName;
        selector += selectorForAttribute(uniqueAttributes.get("id"), "#", true);
        selector += selectorForAttribute(uniqueAttributes.get("class"), ".", true);
        for (let [attribute, values] of uniqueAttributes) {
            if (attribute !== "id" && attribute !== "class")
                selector += `[${attribute}="${selectorForAttribute(values)}"]`;
        }

        if (needsNthChild)
            selector += `:nth-child(${nodeIndex + 1})`;

        return {value: selector, done: false};
    }

    let lowerNodeName = node.nodeName().toLowerCase();

    // html, head, and body are unique nodes.
    if (lowerNodeName === "body" || lowerNodeName === "head" || lowerNodeName === "html")
        return {value: nodeName, done: true};

    // #id is unique.
    let id = node.getAttribute("id");
    if (id)
        return {value: node.escapedIdSelector, done: true};

    // Find uniqueness among siblings.
    //   - look for a unique className
    //   - look for a unique tagName
    //   - fallback to nth-child()

    function classNames(node) {
        let classAttribute = node.getAttribute("class");
        return classAttribute ? classAttribute.trim().split(/\s+/) : [];
    }

    let nthChildIndex = -1;
    let hasUniqueTagName = true;
    let uniqueClasses = new Set(classNames(node));

    let siblings = node.parentNode.children;
    let elementIndex = 0;
    for (let sibling of siblings) {
        if (sibling.nodeType() !== Node.ELEMENT_NODE)
            continue;

        elementIndex++;
        if (sibling === node) {
            nthChildIndex = elementIndex;
            continue;
        }

        if (sibling.nodeNameInCorrectCase() === nodeName)
            hasUniqueTagName = false;

        if (uniqueClasses.size) {
            let siblingClassNames = classNames(sibling);
            for (let className of siblingClassNames)
                uniqueClasses.delete(className);
        }
    }

    let selector = nodeName;
    if (lowerNodeName === "input" && node.getAttribute("type") && !uniqueClasses.size)
        selector += `[type="${node.getAttribute("type")}"]`;
    if (!hasUniqueTagName) {
        if (uniqueClasses.size)
            selector += node.escapedClassSelector;
        else
            selector += `:nth-child(${nthChildIndex})`;
    }

    return {value: selector, done: false};
};

WI.xpath = function(node)
{
    console.assert(node instanceof WI.DOMNode, "Expected a DOMNode.");

    if (node.nodeType() === Node.DOCUMENT_NODE)
        return "/";

    let components = [];
    while (node) {
        let component = WI.xpathComponent(node);
        if (!component)
            break;
        components.push(component);
        if (component.done)
            break;
        node = node.parentNode;
    }

    components.reverse();

    let prefix = components.length && components[0].done ? "" : "/";
    return prefix + components.map((x) => x.value).join("/");
};

WI.xpathComponent = function(node)
{
    console.assert(node instanceof WI.DOMNode, "Expected a DOMNode.");

    let index = WI.xpathIndex(node);
    if (index === -1)
        return null;

    let value;

    switch (node.nodeType()) {
    case Node.DOCUMENT_NODE:
        return {value: "", done: true};
    case Node.ELEMENT_NODE:
        var id = node.getAttribute("id");
        if (id)
            return {value: `//*[@id="${id}"]`, done: true};
        value = node.localName();
        break;
    case Node.ATTRIBUTE_NODE:
        value = `@${node.nodeName()}`;
        break;
    case Node.TEXT_NODE:
    case Node.CDATA_SECTION_NODE:
        value = "text()";
        break;
    case Node.COMMENT_NODE:
        value = "comment()";
        break;
    case Node.PROCESSING_INSTRUCTION_NODE:
        value = "processing-instruction()";
        break;
    default:
        value = "";
        break;
    }

    if (index > 0)
        value += `[${index}]`;

    return {value, done: false};
};

WI.xpathIndex = function(node)
{
    // Root node.
    if (!node.parentNode)
        return 0;

    // No siblings.
    let siblings = node.parentNode.children;
    if (siblings.length <= 1)
        return 0;

    // Find uniqueness among siblings.
    //   - look for a unique localName
    //   - fallback to index

    function isSimiliarNode(a, b) {
        if (a === b)
            return true;

        let aType = a.nodeType();
        let bType = b.nodeType();

        if (aType === Node.ELEMENT_NODE && bType === Node.ELEMENT_NODE)
            return a.localName() === b.localName();

        // XPath CDATA and text() are the same.
        if (aType === Node.CDATA_SECTION_NODE)
            return aType === Node.TEXT_NODE;
        if (bType === Node.CDATA_SECTION_NODE)
            return bType === Node.TEXT_NODE;

        return aType === bType;
    }

    let unique = true;
    let xPathIndex = -1;

    let xPathIndexCounter = 1; // XPath indices start at 1.
    for (let sibling of siblings) {
        if (!isSimiliarNode(node, sibling))
            continue;

        if (node === sibling) {
            xPathIndex = xPathIndexCounter;
            if (!unique)
                return xPathIndex;
        } else {
            unique = false;
            if (xPathIndex !== -1)
                return xPathIndex;
        }

        xPathIndexCounter++;
    }

    if (unique)
        return 0;

    console.assert(xPathIndex > 0, "Should have found the node.");
    return xPathIndex;
};
