/*
 * Copyright (C) 2013 Apple 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:
 * 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.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. 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 INC. 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.DOMNodeStyles = class DOMNodeStyles extends WI.Object
{
    constructor(node)
    {
        super();

        console.assert(node);
        this._node = node || null;

        this._rulesMap = new Map;
        this._stylesMap = new Multimap;

        this._matchedRules = [];
        this._inheritedRules = [];
        this._pseudoElements = new Map;
        this._inlineStyle = null;
        this._attributesStyle = null;
        this._computedStyle = null;
        this._orderedStyles = [];

        this._computedPrimaryFont = null;

        this._propertyNameToEffectivePropertyMap = {};
        this._usedCSSVariables = new Set;
        this._allCSSVariables = new Set;
        this._variableStylesByType = null;

        this._pendingRefreshTask = null;
        this.refresh();

        this._trackedStyleSheets = new WeakSet;
        WI.CSSStyleSheet.addEventListener(WI.CSSStyleSheet.Event.ContentDidChange, this._handleCSSStyleSheetContentDidChange, this);
    }

    // Static

    static parseSelectorListPayload(selectorList)
    {
        let selectors = selectorList.selectors;
        if (!selectors.length)
            return [];

        return selectors.map(function(selectorPayload) {
            return new WI.CSSSelector(selectorPayload.text, selectorPayload.specificity, selectorPayload.dynamic);
        });
    }

    static createSourceCodeLocation(sourceURL, {line, column, documentNode} = {})
    {
        if (!sourceURL)
            return null;

        let sourceCode = null;

        // Try to use the node to find the frame which has the correct resource first.
        if (documentNode) {
            let mainResource = WI.networkManager.resourcesForURL(documentNode.documentURL).firstValue;
            if (mainResource) {
                let parentFrame = mainResource.parentFrame;
                sourceCode = parentFrame.resourcesForURL(sourceURL).firstValue;
            }
        }

        // If that didn't find the resource, then search all frames.
        if (!sourceCode)
            sourceCode = WI.networkManager.resourcesForURL(sourceURL).firstValue;

        if (!sourceCode)
            return null;

        return sourceCode.createSourceCodeLocation(line || 0, column || 0);
    }

    static uniqueOrderedStyles(orderedStyles)
    {
        let uniqueOrderedStyles = [];

        for (let style of orderedStyles) {
            let rule = style.ownerRule;
            if (!rule) {
                uniqueOrderedStyles.push(style);
                continue;
            }

            let found = false;
            for (let existingStyle of uniqueOrderedStyles) {
                if (rule.isEqualTo(existingStyle.ownerRule)) {
                    found = true;
                    break;
                }
            }
            if (!found)
                uniqueOrderedStyles.push(style);
        }

        return uniqueOrderedStyles;
    }

    // Public

    get node() { return this._node; }
    get matchedRules() { return this._matchedRules; }
    get inheritedRules() { return this._inheritedRules; }
    get inlineStyle() { return this._inlineStyle; }
    get attributesStyle() { return this._attributesStyle; }
    get pseudoElements() { return this._pseudoElements; }
    get computedStyle() { return this._computedStyle; }
    get orderedStyles() { return this._orderedStyles; }
    get computedPrimaryFont() { return this._computedPrimaryFont; }
    get usedCSSVariables() { return this._usedCSSVariables; }
    get allCSSVariables() { return this._allCSSVariables; }

    get needsRefresh()
    {
        return this._pendingRefreshTask || this._needsRefresh;
    }

    get uniqueOrderedStyles()
    {
        return WI.DOMNodeStyles.uniqueOrderedStyles(this._orderedStyles);
    }

    get variableStylesByType()
    {
        if (this._variableStylesByType)
            return this._variableStylesByType;

        let properties = this._computedStyle?.properties;
        if (!properties)
            return new Map;

        // Will iterate in order through type checkers for each CSS variable to identify its type.
        // The catch-all "other" must always be last.
        const typeCheckFunctions = [
            {
                type: WI.DOMNodeStyles.VariablesGroupType.Colors,
                checker: (property) => WI.Color.fromString(property.value),
            },
            {
                type: WI.DOMNodeStyles.VariablesGroupType.Dimensions,
                // FIXME: <https://webkit.org/b/233576> build RegExp from `WI.CSSCompletions.lengthUnits`.
                checker: (property) => /^-?\d+(\.\d+)?\D+$/.test(property.value),
            },
            {
                type: WI.DOMNodeStyles.VariablesGroupType.Numbers,
                checker: (property) => /^-?\d+(\.\d+)?$/.test(property.value),
            },
            {
                type: WI.DOMNodeStyles.VariablesGroupType.Other,
                checker: (property) => true,
            },
        ];

        let variablesForType = {};
        for (let property of properties) {
            if (!property.isVariable)
                continue;

            for (let {type, checker} of typeCheckFunctions) {
                if (checker(property)) {
                    variablesForType[type] ||= [];
                    variablesForType[type].push(property);
                    break;
                }
            }
        }

        this._variableStylesByType = new Map;
        for (let {type} of typeCheckFunctions) {
            if (!variablesForType[type]?.length)
                continue;

            const ownerStyleSheet = null;
            const id = null;
            const inherited = false;
            const text = null;
            let style = new WI.CSSStyleDeclaration(this, ownerStyleSheet, id, WI.CSSStyleDeclaration.Type.Computed, this._node, inherited, text, variablesForType[type]);
            this._variableStylesByType.set(type, style);
        }

        return this._variableStylesByType;
    }

    refreshIfNeeded()
    {
        if (this._pendingRefreshTask)
            return this._pendingRefreshTask;
        if (!this._needsRefresh)
            return Promise.resolve(this);
        return this.refresh();
    }

    refresh()
    {
        if (this._pendingRefreshTask)
            return this._pendingRefreshTask;

        this._needsRefresh = false;

        let fetchedMatchedStylesPromise = new WI.WrappedPromise;
        let fetchedInlineStylesPromise = new WI.WrappedPromise;
        let fetchedComputedStylesPromise = new WI.WrappedPromise;
        let fetchedFontDataPromise = new WI.WrappedPromise;

        // Ensure we resolve these promises even in the case of an error.
        function wrap(func, promise) {
            return (...args) => {
                try {
                    func.apply(this, args);
                } catch (e) {
                    console.error(e);
                    promise.resolve();
                }
            };
        }

        let parseRuleMatchArrayPayload = (matchArray, node, inherited, pseudoId) => {
            var result = [];

            // Iterate in reverse order to match the cascade order.
            var ruleOccurrences = {};
            for (var i = matchArray.length - 1; i >= 0; --i) {
                var rule = this._parseRulePayload(matchArray[i].rule, matchArray[i].matchingSelectors, node, inherited, pseudoId, ruleOccurrences);
                if (!rule)
                    continue;
                result.push(rule);
            }

            return result;
        };

        function fetchedMatchedStyles(error, matchedRulesPayload, pseudoElementRulesPayload, inheritedRulesPayload)
        {
            matchedRulesPayload = matchedRulesPayload || [];
            pseudoElementRulesPayload = pseudoElementRulesPayload || [];
            inheritedRulesPayload = inheritedRulesPayload || [];

            this._previousStylesMap = this._stylesMap;
            this._stylesMap = new Multimap;

            this._matchedRules = parseRuleMatchArrayPayload(matchedRulesPayload, this._node);

            this._pseudoElements.clear();
            for (let {pseudoId, matches} of pseudoElementRulesPayload) {
                let pseudoElementRules = parseRuleMatchArrayPayload(matches, this._node, false, pseudoId);
                this._pseudoElements.set(pseudoId, {matchedRules: pseudoElementRules});
            }

            this._inheritedRules = [];

            var i = 0;
            var currentNode = this._node.parentNode;
            while (currentNode && i < inheritedRulesPayload.length) {
                var inheritedRulePayload = inheritedRulesPayload[i];

                var inheritedRuleInfo = {node: currentNode};
                inheritedRuleInfo.inlineStyle = inheritedRulePayload.inlineStyle ? this._parseStyleDeclarationPayload(inheritedRulePayload.inlineStyle, currentNode, true, null, WI.CSSStyleDeclaration.Type.Inline) : null;
                inheritedRuleInfo.matchedRules = inheritedRulePayload.matchedCSSRules ? parseRuleMatchArrayPayload(inheritedRulePayload.matchedCSSRules, currentNode, true) : [];

                if (inheritedRuleInfo.inlineStyle || inheritedRuleInfo.matchedRules.length)
                    this._inheritedRules.push(inheritedRuleInfo);

                currentNode = currentNode.parentNode;
                ++i;
            }

            fetchedMatchedStylesPromise.resolve();
        }

        function fetchedInlineStyles(error, inlineStylePayload, attributesStylePayload)
        {
            this._inlineStyle = inlineStylePayload ? this._parseStyleDeclarationPayload(inlineStylePayload, this._node, false, null, WI.CSSStyleDeclaration.Type.Inline) : null;
            this._attributesStyle = attributesStylePayload ? this._parseStyleDeclarationPayload(attributesStylePayload, this._node, false, null, WI.CSSStyleDeclaration.Type.Attribute) : null;

            this._updateStyleCascade();

            fetchedInlineStylesPromise.resolve();
        }

        function fetchedComputedStyle(error, computedPropertiesPayload)
        {
            var properties = [];
            for (var i = 0; computedPropertiesPayload && i < computedPropertiesPayload.length; ++i) {
                var propertyPayload = computedPropertiesPayload[i];

                var canonicalName = WI.cssManager.canonicalNameForPropertyName(propertyPayload.name);
                propertyPayload.implicit = !this._propertyNameToEffectivePropertyMap[canonicalName];

                var property = this._parseStylePropertyPayload(propertyPayload, NaN, this._computedStyle);
                if (!property.implicit)
                    property.implicit = !this._isPropertyFoundInMatchingRules(property.name);
                properties.push(property);
            }

            if (this._computedStyle)
                this._computedStyle.update(null, properties);
            else
                this._computedStyle = new WI.CSSStyleDeclaration(this, null, null, WI.CSSStyleDeclaration.Type.Computed, this._node, false, null, properties);

            let significantChange = false;
            for (let [key, styles] of this._stylesMap.sets()) {
                // Check if the same key exists in the previous map and has the same style objects.
                let previousStyles = this._previousStylesMap.get(key);
                if (previousStyles) {
                    // Some styles have selectors such that they will match with the DOM node twice (for example "::before, ::after").
                    // In this case a second style for a second matching may be generated and added which will cause the shallowEqual
                    // to not return true, so in this case we just want to ensure that all the current styles existed previously.
                    let styleFound = false;
                    for (let style of styles) {
                        if (previousStyles.has(style)) {
                            styleFound = true;
                            break;
                        }
                    }

                    if (styleFound)
                        continue;
                }

                if (!this._includeUserAgentRulesOnNextRefresh) {
                    // We can assume all the styles with the same key are from the same stylesheet and rule, so we only check the first.
                    let firstStyle = styles.firstValue;
                    if (firstStyle && firstStyle.ownerRule && firstStyle.ownerRule.type === WI.CSSStyleSheet.Type.UserAgent) {
                        // User Agent styles get different identifiers after some edits. This would cause us to fire a significant refreshed
                        // event more than it is helpful. And since the user agent stylesheet is static it shouldn't match differently
                        // between refreshes for the same node. This issue is tracked by: https://webkit.org/b/110055
                        continue;
                    }
                }

                // This key is new or has different style objects than before. This is a significant change.
                significantChange = true;
                break;
            }

            if (!significantChange) {
                for (let [key, previousStyles] of this._previousStylesMap.sets()) {
                    // Check if the same key exists in current map. If it does exist it was already checked for equality above.
                    if (this._stylesMap.has(key))
                        continue;

                    if (!this._includeUserAgentRulesOnNextRefresh) {
                        // See above for why we skip user agent style rules.
                        let firstStyle = previousStyles.firstValue;
                        if (firstStyle && firstStyle.ownerRule && firstStyle.ownerRule.type === WI.CSSStyleSheet.Type.UserAgent)
                            continue;
                    }

                    // This key no longer exists. This is a significant change.
                    significantChange = true;
                    break;
                }
            }

            if (significantChange)
                this._variableStylesByType = null;

            this._previousStylesMap = null;
            this._includeUserAgentRulesOnNextRefresh = false;

            fetchedComputedStylesPromise.resolve({significantChange});
        }

        function fetchedFontData(error, fontDataPayload)
        {
            if (fontDataPayload)
                this._computedPrimaryFont = WI.Font.fromPayload(fontDataPayload);
            else
                this._computedPrimaryFont = null;

            fetchedFontDataPromise.resolve();
        }

        let target = WI.assumingMainTarget();
        target.CSSAgent.getMatchedStylesForNode.invoke({nodeId: this._node.id, includePseudo: true, includeInherited: true}, wrap.call(this, fetchedMatchedStyles, fetchedMatchedStylesPromise));
        target.CSSAgent.getInlineStylesForNode.invoke({nodeId: this._node.id}, wrap.call(this, fetchedInlineStyles, fetchedInlineStylesPromise));
        target.CSSAgent.getComputedStyleForNode.invoke({nodeId: this._node.id}, wrap.call(this, fetchedComputedStyle, fetchedComputedStylesPromise));

        // COMPATIBILITY (iOS 14.0): `CSS.getFontDataForNode` did not exist yet.
        if (InspectorBackend.hasCommand("CSS.getFontDataForNode"))
            target.CSSAgent.getFontDataForNode.invoke({nodeId: this._node.id}, wrap.call(this, fetchedFontData, fetchedFontDataPromise));
        else
            fetchedFontDataPromise.resolve();

        this._pendingRefreshTask = Promise.all([fetchedComputedStylesPromise.promise, fetchedMatchedStylesPromise.promise, fetchedInlineStylesPromise.promise, fetchedFontDataPromise.promise])
        .then(([fetchComputedStylesResult]) => {
            this._pendingRefreshTask = null;
            this.dispatchEventToListeners(WI.DOMNodeStyles.Event.Refreshed, {
                significantChange: fetchComputedStylesResult.significantChange,
            });
            return this;
        });

        return this._pendingRefreshTask;
    }

    addRule(selector, text, styleSheetId)
    {
        selector = selector || this._node.appropriateSelectorFor(true);

        let target = WI.assumingMainTarget();

        function completed()
        {
            target.DOMAgent.markUndoableState();
            this.refresh();
        }

        function styleChanged(error, stylePayload)
        {
            if (error)
                return;

            completed.call(this);
        }

        function addedRule(error, rulePayload)
        {
            if (error)
                return;

            if (!text || !text.length) {
                completed.call(this);
                return;
            }

            target.CSSAgent.setStyleText(rulePayload.style.styleId, text, styleChanged.bind(this));
        }

        function inspectorStyleSheetAvailable(styleSheet)
        {
            if (!styleSheet)
                return;

            target.CSSAgent.addRule(styleSheet.id, selector, addedRule.bind(this));
        }

        if (styleSheetId)
            inspectorStyleSheetAvailable.call(this, WI.cssManager.styleSheetForIdentifier(styleSheetId));
        else
            WI.cssManager.preferredInspectorStyleSheetForFrame(this._node.frame, inspectorStyleSheetAvailable.bind(this));
    }

    effectivePropertyForName(name)
    {
        let property = this._propertyNameToEffectivePropertyMap[name];
        if (property)
            return property;

        let canonicalName = WI.cssManager.canonicalNameForPropertyName(name);
        return this._propertyNameToEffectivePropertyMap[canonicalName] || null;
    }

    // Protected

    mediaQueryResultDidChange()
    {
        this._markAsNeedsRefresh();
    }

    pseudoClassesDidChange(node)
    {
        this._includeUserAgentRulesOnNextRefresh = true;
        this._markAsNeedsRefresh();
    }

    attributeDidChange(node, attributeName)
    {
        this._markAsNeedsRefresh();
    }

    changeRuleSelector(rule, selector)
    {
        selector = selector || "";
        let result = new WI.WrappedPromise;

        let target = WI.assumingMainTarget();

        function ruleSelectorChanged(error, rulePayload)
        {
            if (error) {
                result.reject(error);
                return;
            }

            target.DOMAgent.markUndoableState();

            // Do a full refresh incase the rule no longer matches the node or the
            // matched selector indices changed.
            this.refresh().then(() => {
                result.resolve(rulePayload);
            });
        }

        this._needsRefresh = true;
        this._ignoreNextContentDidChangeForStyleSheet = rule.ownerStyleSheet;

        target.CSSAgent.setRuleSelector(rule.id, selector, ruleSelectorChanged.bind(this));
        return result.promise;
    }

    changeStyleText(style, text, callback)
    {
        if (!style.ownerStyleSheet || !style.styleSheetTextRange) {
            callback();
            return;
        }

        text = text || "";

        let didSetStyleText = (error, stylePayload) => {
            if (error) {
                callback(error);
                return;
            }
            callback();

            // Update validity of each property for rules that don't match the selected DOM node.
            // These rules don't get updated by CSSAgent.getMatchedStylesForNode.
            if (style.ownerRule && !style.ownerRule.matchedSelectorIndices.length)
                this._parseStyleDeclarationPayload(stylePayload, this._node, false, null, style.type, style.ownerRule, false);

            this.refresh();
        };

        let target = WI.assumingMainTarget();
        target.CSSAgent.setStyleText(style.id, text, didSetStyleText);
    }

    // Private

    _parseSourceRangePayload(payload)
    {
        if (!payload)
            return null;

        return new WI.TextRange(payload.startLine, payload.startColumn, payload.endLine, payload.endColumn);
    }

    _parseStylePropertyPayload(payload, index, styleDeclaration)
    {
        var text = payload.text || "";
        var name = payload.name;
        var value = payload.value || "";
        var priority = payload.priority || "";
        let range = payload.range || null;

        var enabled = true;
        var overridden = false;
        var implicit = payload.implicit || false;
        var anonymous = false;
        var valid = "parsedOk" in payload ? payload.parsedOk : true;

        switch (payload.status || "style") {
        case "active":
            enabled = true;
            break;
        case "inactive":
            overridden = true;
            enabled = true;
            break;
        case "disabled":
            enabled = false;
            break;
        case "style":
            // FIXME: Is this still needed? This includes UserAgent styles and HTML attribute styles.
            anonymous = true;
            break;
        }

        if (range) {
            // Last property of inline style has mismatching range.
            // The actual text has one line, but the range spans two lines.
            let rangeLineCount = 1 + range.endLine - range.startLine;
            if (rangeLineCount > 1) {
                let textLineCount = text.lineCount;
                if (textLineCount === rangeLineCount - 1) {
                    range.endLine = range.startLine + (textLineCount - 1);
                    range.endColumn = range.startColumn + text.lastLine.length;
                }
            }
        }

        var styleSheetTextRange = this._parseSourceRangePayload(payload.range);

        if (styleDeclaration) {
            // Use propertyForName when the index is NaN since propertyForName is fast in that case.
            var property = isNaN(index) ? styleDeclaration.propertyForName(name) : styleDeclaration.enabledProperties[index];

            // Reuse a property if the index and name matches. Otherwise it is a different property
            // and should be created from scratch. This works in the simple cases where only existing
            // properties change in place and no properties are inserted or deleted at the beginning.
            // FIXME: This could be smarter by ignoring index and just go by name. However, that gets
            // tricky for rules that have more than one property with the same name.
            if (property && property.name === name && (property.index === index || (isNaN(property.index) && isNaN(index)))) {
                property.update(text, name, value, priority, enabled, overridden, implicit, anonymous, valid, styleSheetTextRange);
                return property;
            }

            // Reuse a pending property with the same name. These properties are pending being committed,
            // so if we find a match that likely means it got committed and we should use it.
            var pendingProperties = styleDeclaration.pendingProperties;
            for (var i = 0; i < pendingProperties.length; ++i) {
                var pendingProperty = pendingProperties[i];
                if (pendingProperty.name === name && isNaN(pendingProperty.index)) {
                    pendingProperty.index = index;
                    pendingProperty.update(text, name, value, priority, enabled, overridden, implicit, anonymous, valid, styleSheetTextRange);
                    return pendingProperty;
                }
            }
        }

        return new WI.CSSProperty(index, text, name, value, priority, enabled, overridden, implicit, anonymous, valid, styleSheetTextRange);
    }

    _parseStyleDeclarationPayload(payload, node, inherited, pseudoId, type, rule, matchesNode = true)
    {
        if (!payload)
            return null;

        rule = rule || null;
        inherited = inherited || false;

        var id = payload.styleId;
        var mapKey = id ? id.styleSheetId + ":" + id.ordinal : null;
        if (pseudoId)
            mapKey += ":" + pseudoId;
        if (type === WI.CSSStyleDeclaration.Type.Attribute)
            mapKey += ":" + node.id + ":attribute";

        let style = rule ? rule.style : null;
        console.assert(matchesNode || style);

        if (matchesNode) {
            console.assert(this._previousStylesMap);
            let existingStyles = this._previousStylesMap.get(mapKey);
            if (existingStyles && !style) {
                for (let existingStyle of existingStyles) {
                    if (existingStyle.node === node && existingStyle.inherited === inherited) {
                        style = existingStyle;
                        break;
                    }
                }
            }

            if (style)
                this._stylesMap.add(mapKey, style);
        }

        var inheritedPropertyCount = 0;

        var properties = [];
        for (var i = 0; payload.cssProperties && i < payload.cssProperties.length; ++i) {
            var propertyPayload = payload.cssProperties[i];

            if (inherited && WI.CSSProperty.isInheritedPropertyName(propertyPayload.name))
                ++inheritedPropertyCount;

            let property = this._parseStylePropertyPayload(propertyPayload, i, style);
            properties.push(property);
        }

        let text = payload.cssText;
        var styleSheetTextRange = this._parseSourceRangePayload(payload.range);

        if (style) {
            style.update(text, properties, styleSheetTextRange);
            return style;
        }

        if (!matchesNode)
            return null;

        var styleSheet = id ? WI.cssManager.styleSheetForIdentifier(id.styleSheetId) : null;
        if (styleSheet) {
            if (type === WI.CSSStyleDeclaration.Type.Inline)
                styleSheet.markAsInlineStyleAttributeStyleSheet();
            this._trackedStyleSheets.add(styleSheet);
        }

        if (inherited && !inheritedPropertyCount)
            return null;

        style = new WI.CSSStyleDeclaration(this, styleSheet, id, type, node, inherited, text, properties, styleSheetTextRange);

        if (mapKey)
            this._stylesMap.add(mapKey, style);

        return style;
    }

    _parseRulePayload(payload, matchedSelectorIndices, node, inherited, pseudoId, ruleOccurrences)
    {
        if (!payload)
            return null;

        // User and User Agent rules don't have 'ruleId' in the payload. However, their style's have 'styleId' and
        // 'styleId' is the same identifier the backend uses for Author rule identifiers, so do the same here.
        // They are excluded by the backend because they are not editable, however our front-end does not determine
        // editability solely based on the existence of the id like the open source front-end does.
        var id = payload.ruleId || payload.style.styleId;

        var mapKey = id ? id.styleSheetId + ":" + id.ordinal + ":" + (inherited ? "I" : "N") + ":" + (pseudoId ? pseudoId + ":" : "") + node.id : null;

        // Rules can match multiple times if they have multiple selectors or because of inheritance. We keep a count
        // of occurrences so we have unique rules per occurrence, that way properties will be correctly marked as overridden.
        var occurrence = 0;
        if (mapKey) {
            if (mapKey in ruleOccurrences)
                occurrence = ++ruleOccurrences[mapKey];
            else
                ruleOccurrences[mapKey] = occurrence;

            // Append the occurrence number to the map key for lookup in the rules map.
            mapKey += ":" + occurrence;
        }

        let rule = this._rulesMap.get(mapKey);

        var style = this._parseStyleDeclarationPayload(payload.style, node, inherited, pseudoId, WI.CSSStyleDeclaration.Type.Rule, rule);
        if (!style)
            return null;

        var styleSheet = id ? WI.cssManager.styleSheetForIdentifier(id.styleSheetId) : null;

        var selectorText = payload.selectorList.text;
        let selectors = DOMNodeStyles.parseSelectorListPayload(payload.selectorList);
        var type = WI.CSSManager.protocolStyleSheetOriginToEnum(payload.origin);

        var sourceCodeLocation = null;
        var sourceRange = payload.selectorList.range;
        if (sourceRange) {
            sourceCodeLocation = DOMNodeStyles.createSourceCodeLocation(payload.sourceURL, {
                line: sourceRange.startLine,
                column: sourceRange.startColumn,
                documentNode: this._node.ownerDocument,
            });
        } else {
            // FIXME: Is it possible for a CSSRule to have a sourceLine without its selectorList having a sourceRange? Fall back just in case.
            sourceCodeLocation = DOMNodeStyles.createSourceCodeLocation(payload.sourceURL, {
                line: payload.sourceLine,
                documentNode: this._node.ownerDocument,
            });
        }

        if (styleSheet) {
            if (!sourceCodeLocation && sourceRange)
                sourceCodeLocation = styleSheet.createSourceCodeLocation(sourceRange.startLine, sourceRange.startColumn);
            sourceCodeLocation = styleSheet.offsetSourceCodeLocation(sourceCodeLocation);
        }

        // COMPATIBILITY (iOS 13): CSS.CSSRule.groupings did not exist yet.
        let groupings = (payload.groupings || payload.media || []).map((grouping) => {
            let groupingType = WI.CSSManager.protocolGroupingTypeToEnum(grouping.type || grouping.source);
            let groupingSourceCodeLocation = DOMNodeStyles.createSourceCodeLocation(grouping.sourceURL);
            if (styleSheet)
                groupingSourceCodeLocation = styleSheet.offsetSourceCodeLocation(groupingSourceCodeLocation);
            return new WI.CSSGrouping(groupingType, grouping.text, groupingSourceCodeLocation);
        });

        if (rule) {
            rule.update(sourceCodeLocation, selectorText, selectors, matchedSelectorIndices, style, groupings);
            return rule;
        }

        if (styleSheet)
            this._trackedStyleSheets.add(styleSheet);

        rule = new WI.CSSRule(this, styleSheet, id, type, sourceCodeLocation, selectorText, selectors, matchedSelectorIndices, style, groupings);

        if (mapKey)
            this._rulesMap.set(mapKey, rule);

        return rule;
    }

    _markAsNeedsRefresh()
    {
        this._needsRefresh = true;
        this.dispatchEventToListeners(WI.DOMNodeStyles.Event.NeedsRefresh);
    }

    _handleCSSStyleSheetContentDidChange(event)
    {
        let styleSheet = event.target;
        if (!this._trackedStyleSheets.has(styleSheet))
            return;

        // Ignore the stylesheet we know we just changed and handled above.
        if (styleSheet === this._ignoreNextContentDidChangeForStyleSheet) {
            this._ignoreNextContentDidChangeForStyleSheet = null;
            return;
        }

        this._markAsNeedsRefresh();
    }

    _updateStyleCascade()
    {
        var cascadeOrderedStyleDeclarations = this._collectStylesInCascadeOrder(this._matchedRules, this._inlineStyle, this._attributesStyle);

        for (var i = 0; i < this._inheritedRules.length; ++i) {
            var inheritedStyleInfo = this._inheritedRules[i];
            var inheritedCascadeOrder = this._collectStylesInCascadeOrder(inheritedStyleInfo.matchedRules, inheritedStyleInfo.inlineStyle, null);
            cascadeOrderedStyleDeclarations.pushAll(inheritedCascadeOrder);
        }

        this._orderedStyles = cascadeOrderedStyleDeclarations;

        this._propertyNameToEffectivePropertyMap = {};

        this._associateRelatedProperties(cascadeOrderedStyleDeclarations, this._propertyNameToEffectivePropertyMap);
        this._markOverriddenProperties(cascadeOrderedStyleDeclarations, this._propertyNameToEffectivePropertyMap);
        this._collectCSSVariables(cascadeOrderedStyleDeclarations);

        for (let pseudoElementInfo of this._pseudoElements.values()) {
            pseudoElementInfo.orderedStyles = this._collectStylesInCascadeOrder(pseudoElementInfo.matchedRules, null, null);
            this._associateRelatedProperties(pseudoElementInfo.orderedStyles);
            this._markOverriddenProperties(pseudoElementInfo.orderedStyles);
        }
    }

    _collectStylesInCascadeOrder(matchedRules, inlineStyle, attributesStyle)
    {
        var result = [];

        // Inline style has the greatest specificity. So it goes first in the cascade order.
        if (inlineStyle)
            result.push(inlineStyle);

        var userAndUserAgentStyles = [];

        for (var i = 0; i < matchedRules.length; ++i) {
            var rule = matchedRules[i];

            // Only append to the result array here for author and inspector rules since attribute
            // styles come between author rules and user/user agent rules.
            switch (rule.type) {
            case WI.CSSStyleSheet.Type.Inspector:
            case WI.CSSStyleSheet.Type.Author:
                result.push(rule.style);
                break;

            case WI.CSSStyleSheet.Type.User:
            case WI.CSSStyleSheet.Type.UserAgent:
                userAndUserAgentStyles.push(rule.style);
                break;
            }
        }

        // Style properties from HTML attributes are next.
        if (attributesStyle)
            result.push(attributesStyle);

        // Finally add the user and user stylesheet's matched style rules we collected earlier.
        result.pushAll(userAndUserAgentStyles);

        return result;
    }

    _markOverriddenProperties(styles, propertyNameToEffectiveProperty)
    {
        propertyNameToEffectiveProperty = propertyNameToEffectiveProperty || {};

        function isOverriddenByRelatedShorthand(property) {
            let shorthand = property.relatedShorthandProperty;
            if (!shorthand)
                return false;

            if (property.important && !shorthand.important)
                return false;

            if (!property.important && shorthand.important)
                return true;

            if (property.ownerStyle === shorthand.ownerStyle)
                return shorthand.index > property.index;

            let propertyStyleIndex = styles.indexOf(property.ownerStyle);
            let shorthandStyleIndex = styles.indexOf(shorthand.ownerStyle);
            return shorthandStyleIndex > propertyStyleIndex;
        }

        for (var i = 0; i < styles.length; ++i) {
            var style = styles[i];
            var properties = style.enabledProperties;

            for (var j = 0; j < properties.length; ++j) {
                var property = properties[j];
                if (!property.attached || !property.valid) {
                    property.overridden = false;
                    continue;
                }

                if (style.inherited && !property.inherited) {
                    property.overridden = false;
                    continue;
                }

                var canonicalName = property.canonicalName;
                if (canonicalName in propertyNameToEffectiveProperty) {
                    var effectiveProperty = propertyNameToEffectiveProperty[canonicalName];

                    if (effectiveProperty.ownerStyle === property.ownerStyle) {
                        if (effectiveProperty.important && !property.important) {
                            property.overridden = true;
                            property.overridingProperty = effectiveProperty;
                            continue;
                        }
                    } else if (effectiveProperty.important || !property.important || effectiveProperty.ownerStyle.node !== property.ownerStyle.node) {
                        property.overridden = true;
                        property.overridingProperty = effectiveProperty;
                        continue;
                    }

                    if (!property.anonymous) {
                        effectiveProperty.overridden = true;
                        effectiveProperty.overridingProperty = property;
                    }
                }

                if (isOverriddenByRelatedShorthand(property)) {
                    property.overridden = true;
                    property.overridingProperty = property.relatedShorthandProperty;
                } else
                    property.overridden = false;

                propertyNameToEffectiveProperty[canonicalName] = property;
            }
        }
    }

    _associateRelatedProperties(styles, propertyNameToEffectiveProperty)
    {
        for (var i = 0; i < styles.length; ++i) {
            var properties = styles[i].enabledProperties;

            var knownShorthands = {};

            for (var j = 0; j < properties.length; ++j) {
                var property = properties[j];

                if (!property.valid)
                    continue;

                if (!WI.CSSKeywordCompletions.LonghandNamesForShorthandProperty.has(property.name))
                    continue;

                if (knownShorthands[property.canonicalName] && !knownShorthands[property.canonicalName].overridden) {
                    console.assert(property.overridden);
                    continue;
                }

                knownShorthands[property.canonicalName] = property;
            }

            for (var j = 0; j < properties.length; ++j) {
                var property = properties[j];

                if (!property.valid)
                    continue;

                var shorthandProperty = null;

                if (!isEmptyObject(knownShorthands)) {
                    var possibleShorthands = WI.CSSKeywordCompletions.ShorthandNamesForLongHandProperty.get(property.canonicalName) || [];
                    for (var k = 0; k < possibleShorthands.length; ++k) {
                        if (possibleShorthands[k] in knownShorthands) {
                            shorthandProperty = knownShorthands[possibleShorthands[k]];
                            break;
                        }
                    }
                }

                if (!shorthandProperty || shorthandProperty.overridden !== property.overridden) {
                    property.relatedShorthandProperty = null;
                    property.clearRelatedLonghandProperties();
                    continue;
                }

                shorthandProperty.addRelatedLonghandProperty(property);
                property.relatedShorthandProperty = shorthandProperty;

                if (propertyNameToEffectiveProperty && propertyNameToEffectiveProperty[shorthandProperty.canonicalName] === shorthandProperty)
                    propertyNameToEffectiveProperty[property.canonicalName] = property;
            }
        }
    }

    _collectCSSVariables(styles)
    {
        this._allCSSVariables = new Set;
        this._usedCSSVariables = new Set;

        for (let style of styles) {
            for (let property of style.enabledProperties) {
                if (property.isVariable)
                    this._allCSSVariables.add(property.name);

                let variables = WI.CSSProperty.findVariableNames(property.value);

                if (!style.inherited) {
                    // FIXME: <https://webkit.org/b/226648> Support the case of variables declared on matching styles but not used anywhere.
                    this._usedCSSVariables.addAll(variables);
                    continue;
                }

                // Always collect variables used in values of inheritable properties.
                if (WI.CSSKeywordCompletions.InheritedProperties.has(property.name)) {
                    this._usedCSSVariables.addAll(variables);
                    continue;
                }

                // For variables from inherited styles, leverage the fact that styles are already sorted in cascade order to support inherited variables referencing other variables.
                // If the variable was found to be used before, collect any variables used in its declaration value
                // (if any variables are found, this isn't the end of the variable reference chain in the inheritance stack).
                if (property.isVariable && this._usedCSSVariables.has(property.name))
                    this._usedCSSVariables.addAll(variables);
            }
        }
    }

    _isPropertyFoundInMatchingRules(propertyName)
    {
        return this._orderedStyles.some((style) => {
            return style.enabledProperties.some((property) => property.name === propertyName);
        });
    }
};

WI.DOMNodeStyles.Event = {
    NeedsRefresh: "dom-node-styles-needs-refresh",
    Refreshed: "dom-node-styles-refreshed"
};

WI.DOMNodeStyles.VariablesGroupType = {
    Ungrouped: "ungrouped",
    Colors: "colors",
    Dimensions: "dimensions",
    Numbers: "numbers",
    Other: "other",
};
