/*
 * Copyright (C) 2017 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.DOMDebuggerManager = class DOMDebuggerManager extends WI.Object
{
    constructor()
    {
        super();

        this._domBreakpointURLMap = new Multimap;
        this._domBreakpointFrameIdentifierMap = new Map;
        this._clearingDOMBreakpointsForRemovedDOMNode = false;

        this._listenerBreakpoints = [];
        this._allAnimationFramesBreakpoint = null;
        this._allIntervalsBreakpoint = null;
        this._allListenersBreakpoint = null;
        this._allTimeoutsBreakpoint = null;

        this._urlBreakpoints = [];
        this._allRequestsBreakpoint = null;

        WI.DOMBreakpoint.addEventListener(WI.Breakpoint.Event.DisabledStateDidChange, this._handleDOMBreakpointDisabledStateChanged, this);
        WI.DOMBreakpoint.addEventListener(WI.Breakpoint.Event.ConditionDidChange, this._handleDOMBreakpointEditablePropertyChanged, this);
        WI.DOMBreakpoint.addEventListener(WI.Breakpoint.Event.IgnoreCountDidChange, this._handleDOMBreakpointEditablePropertyChanged, this);
        WI.DOMBreakpoint.addEventListener(WI.Breakpoint.Event.AutoContinueDidChange, this._handleDOMBreakpointEditablePropertyChanged, this);
        WI.DOMBreakpoint.addEventListener(WI.Breakpoint.Event.ActionsDidChange, this._handleDOMBreakpointActionsChanged, this);
        WI.DOMBreakpoint.addEventListener(WI.DOMBreakpoint.Event.DOMNodeWillChange, this._handleDOMBreakpointDOMNodeWillChange, this);
        WI.DOMBreakpoint.addEventListener(WI.DOMBreakpoint.Event.DOMNodeDidChange, this._handleDOMBreakpointDOMNodeDidChange, this);

        WI.EventBreakpoint.addEventListener(WI.Breakpoint.Event.DisabledStateDidChange, this._handleEventBreakpointDisabledStateChanged, this);
        WI.EventBreakpoint.addEventListener(WI.Breakpoint.Event.ConditionDidChange, this._handleEventBreakpointEditablePropertyChanged, this);
        WI.EventBreakpoint.addEventListener(WI.Breakpoint.Event.IgnoreCountDidChange, this._handleEventBreakpointEditablePropertyChanged, this);
        WI.EventBreakpoint.addEventListener(WI.Breakpoint.Event.AutoContinueDidChange, this._handleEventBreakpointEditablePropertyChanged, this);
        WI.EventBreakpoint.addEventListener(WI.Breakpoint.Event.ActionsDidChange, this._handleEventBreakpointActionsChanged, this);

        WI.URLBreakpoint.addEventListener(WI.Breakpoint.Event.DisabledStateDidChange, this._handleURLBreakpointDisabledStateChanged, this);
        WI.URLBreakpoint.addEventListener(WI.Breakpoint.Event.ConditionDidChange, this._handleURLBreakpointEditablePropertyChanged, this);
        WI.URLBreakpoint.addEventListener(WI.Breakpoint.Event.IgnoreCountDidChange, this._handleURLBreakpointEditablePropertyChanged, this);
        WI.URLBreakpoint.addEventListener(WI.Breakpoint.Event.AutoContinueDidChange, this._handleURLBreakpointEditablePropertyChanged, this);
        WI.URLBreakpoint.addEventListener(WI.Breakpoint.Event.ActionsDidChange, this._handleURLBreakpointActionsChanged, this);

        WI.domManager.addEventListener(WI.DOMManager.Event.NodeRemoved, this._nodeRemoved, this);
        WI.domManager.addEventListener(WI.DOMManager.Event.NodeInserted, this._nodeInserted, this);

        WI.networkManager.addEventListener(WI.NetworkManager.Event.MainFrameDidChange, this._mainFrameDidChange, this);

        WI.Frame.addEventListener(WI.Frame.Event.ChildFrameWasRemoved, this._childFrameWasRemoved, this);
        WI.Frame.addEventListener(WI.Frame.Event.MainResourceDidChange, this._mainResourceDidChange, this);

        let loadBreakpoints = (constructor, objectStore, oldSettings, callback) => {
            WI.Target.registerInitializationPromise((async () => {
                for (let key of oldSettings) {
                    let existingSerializedBreakpoints = WI.Setting.migrateValue(key);
                    if (existingSerializedBreakpoints) {
                        for (let existingSerializedBreakpoint of existingSerializedBreakpoints)
                            await objectStore.putObject(constructor.fromJSON(existingSerializedBreakpoint));
                    }
                }

                let serializedBreakpoints = await objectStore.getAll();

                this._restoringBreakpoints = true;
                for (let serializedBreakpoint of serializedBreakpoints) {
                    let breakpoint = constructor.fromJSON(serializedBreakpoint);

                    const key = null;
                    objectStore.associateObject(breakpoint, key, serializedBreakpoint);

                    callback(breakpoint);
                }
                this._restoringBreakpoints = false;
            })());
        };

        function loadLegacySpecialBreakpoint(shownSettingsKey, enabledSettingsKey, callback) {
            if (!WI.Setting.migrateValue(shownSettingsKey))
                return;

            return callback({
                disabled: !WI.Setting.migrateValue(enabledSettingsKey),
            });
        }

        if (DOMDebuggerManager.supportsDOMBreakpoints()) {
            loadBreakpoints(WI.DOMBreakpoint, WI.objectStores.domBreakpoints, ["dom-breakpoints"], (breakpoint) => {
                this.addDOMBreakpoint(breakpoint);
            });
        }

        if (DOMDebuggerManager.supportsEventBreakpoints() || DOMDebuggerManager.supportsEventListenerBreakpoints()) {
            loadBreakpoints(WI.EventBreakpoint, WI.objectStores.eventBreakpoints, ["event-breakpoints"], (breakpoint) => {
                this.addEventBreakpoint(breakpoint);
            });

            this._allAnimationFramesBreakpoint ??= loadLegacySpecialBreakpoint("show-all-animation-frames-breakpoint", "break-on-all-animation-frames", (options) => new WI.EventBreakpoint(WI.EventBreakpoint.Type.AnimationFrame, options));
            this._allIntervalsBreakpoint ??= loadLegacySpecialBreakpoint("show-all-inteverals-breakpoint", "break-on-all-intervals", (options) => new WI.EventBreakpoint(WI.EventBreakpoint.Type.Interval, options));
            this._allListenersBreakpoint ??= loadLegacySpecialBreakpoint("show-all-listeners-breakpoint", "break-on-all-listeners", (options) => new WI.EventBreakpoint(WI.EventBreakpoint.Type.Listener, options));
            this._allTimeoutsBreakpoint ??= loadLegacySpecialBreakpoint("show-all-timeouts-breakpoint", "break-on-all-timeouts", (options) => new WI.EventBreakpoint(WI.EventBreakpoint.Type.Timeout, options));
        }

        if (DOMDebuggerManager.supportsURLBreakpoints() || DOMDebuggerManager.supportsXHRBreakpoints()) {
            loadBreakpoints(WI.URLBreakpoint, WI.objectStores.urlBreakpoints, ["xhr-breakpoints", "url-breakpoints"], (breakpoint) => {
                this.addURLBreakpoint(breakpoint);
            });

            this._allRequestsBreakpoint ??= loadLegacySpecialBreakpoint("show-all-requests-breakpoint", "break-on-all-requests", (options) => new WI.URLBreakpoint(WI.URLBreakpoint.Type.Text, "", options));
        }
    }

    // Target

    initializeTarget(target)
    {
        if (target.hasDomain("DOMDebugger")) {
            this._restoringBreakpoints = true;

            if (target === WI.assumingMainTarget() && target.mainResource)
                this._speculativelyResolveDOMBreakpointsForURL(target.mainResource.url);

            if (this._allAnimationFramesBreakpoint && !this._allAnimationFramesBreakpoint.disabled)
                this._setEventBreakpoint(this._allAnimationFramesBreakpoint, target);

            if (this._allIntervalsBreakpoint && !this._allIntervalsBreakpoint.disabled)
                this._setEventBreakpoint(this._allIntervalsBreakpoint, target);

            if (this._allListenersBreakpoint && !this._allListenersBreakpoint.disabled)
                this._setEventBreakpoint(this._allListenersBreakpoint, target);

            if (this._allTimeoutsBreakpoint && !this._allTimeoutsBreakpoint.disabled)
                this._setEventBreakpoint(this._allTimeoutsBreakpoint, target);

            if (this._allRequestsBreakpoint)
                this._setURLBreakpoint(this._allRequestsBreakpoint, target);

            for (let breakpoint of this._listenerBreakpoints) {
                if (!breakpoint.disabled)
                    this._setEventBreakpoint(breakpoint, target);
            }

            for (let breakpoint of this._urlBreakpoints) {
                if (!breakpoint.disabled)
                    this._setURLBreakpoint(breakpoint, target);
            }

            this._restoringBreakpoints = false;
        }
    }

    // Static

    static supportsDOMBreakpoints()
    {
        return InspectorBackend.hasCommand("DOMDebugger.setDOMBreakpoint")
            && InspectorBackend.hasCommand("DOMDebugger.removeDOMBreakpoint");
    }

    static supportsEventBreakpoints()
    {
        // COMPATIBILITY (iOS 13): DOMDebugger.setEventBreakpoint and DOMDebugger.removeEventBreakpoint did not exist yet.
        return InspectorBackend.hasCommand("DOMDebugger.setEventBreakpoint")
            && InspectorBackend.hasCommand("DOMDebugger.removeEventBreakpoint");
    }

    static supportsEventListenerBreakpoints()
    {
        // COMPATIBILITY (iOS 12.2): Replaced by DOMDebugger.setEventBreakpoint and DOMDebugger.removeEventBreakpoint.
        return InspectorBackend.hasCommand("DOMDebugger.setEventListenerBreakpoint")
            && InspectorBackend.hasCommand("DOMDebugger.removeEventListenerBreakpoint");
    }

    static supportsURLBreakpoints()
    {
        // COMPATIBILITY (iOS 13): DOMDebugger.setURLBreakpoint and DOMDebugger.removeURLBreakpoint did not exist yet.
        return InspectorBackend.hasCommand("DOMDebugger.setURLBreakpoint")
            && InspectorBackend.hasCommand("DOMDebugger.removeURLBreakpoint");
    }

    static supportsXHRBreakpoints()
    {
        // COMPATIBILITY (iOS 13): Replaced by DOMDebugger.setURLBreakpoint and DOMDebugger.removeURLBreakpoint.
        return InspectorBackend.hasCommand("DOMDebugger.setXHRBreakpoint")
            && InspectorBackend.hasCommand("DOMDebugger.removeXHRBreakpoint");
    }

    static supportsAllListenersBreakpoint()
    {
        // COMPATIBILITY (iOS 13): DOMDebugger.EventBreakpointType.Interval and DOMDebugger.EventBreakpointType.Timeout did not exist yet.
        return DOMDebuggerManager.supportsEventBreakpoints()
            && InspectorBackend.Enum.DOMDebugger.EventBreakpointType.Interval
            && InspectorBackend.Enum.DOMDebugger.EventBreakpointType.Timeout;
    }

    // Public

    get supported()
    {
        return InspectorBackend.hasDomain("DOMDebugger");
    }

    get allAnimationFramesBreakpoint() { return this._allAnimationFramesBreakpoint; }
    get allIntervalsBreakpoint() { return this._allIntervalsBreakpoint; }
    get allListenersBreakpoint() { return this._allListenersBreakpoint; }
    get allTimeoutsBreakpoint() { return this._allTimeoutsBreakpoint; }
    get allRequestsBreakpoint() { return this._allRequestsBreakpoint; }

    get domBreakpoints()
    {
        let mainFrame = WI.networkManager.mainFrame;
        if (!mainFrame)
            return [];

        let resolvedBreakpoints = [];
        let frames = [mainFrame];
        while (frames.length) {
            let frame = frames.shift();

            let domBreakpointNodeIdentifierMap = this._domBreakpointFrameIdentifierMap.get(frame);
            if (domBreakpointNodeIdentifierMap)
                resolvedBreakpoints.pushAll(domBreakpointNodeIdentifierMap.values());

            frames.pushAll(frame.childFrameCollection);
        }

        return resolvedBreakpoints;
    }

    get listenerBreakpoints() { return this._listenerBreakpoints; }
    get urlBreakpoints() { return this._urlBreakpoints; }

    domBreakpointsForNode(node)
    {
        console.assert(node instanceof WI.DOMNode);

        if (!node || !node.frame)
            return [];

        let domBreakpointNodeIdentifierMap = this._domBreakpointFrameIdentifierMap.get(node.frame);
        if (!domBreakpointNodeIdentifierMap)
            return [];

        let breakpoints = domBreakpointNodeIdentifierMap.get(node);
        return breakpoints ? Array.from(breakpoints) : [];
    }

    domBreakpointsInSubtree(node)
    {
        console.assert(node instanceof WI.DOMNode);

        let breakpoints = [];

        if (node.children) {
            let children = Array.from(node.children);
            while (children.length) {
                let child = children.pop();
                if (child.children)
                    children.pushAll(child.children);
                breakpoints.pushAll(this.domBreakpointsForNode(child));
            }
        }

        return breakpoints;
    }

    addDOMBreakpoint(breakpoint)
    {
        console.assert(breakpoint instanceof WI.DOMBreakpoint, breakpoint);
        console.assert(breakpoint.url, breakpoint);
        if (!breakpoint || !breakpoint.url)
            return;

        console.assert(!breakpoint.special, breakpoint);

        this._domBreakpointURLMap.add(breakpoint.url, breakpoint);

        if (breakpoint.domNode) {
            this._resolveDOMBreakpoint(breakpoint, breakpoint.domNode);

            if (!breakpoint.disabled) {
                // We should get the target associated with the nodeIdentifier of this breakpoint.
                let target = WI.assumingMainTarget();
                if (target)
                    this._setDOMBreakpoint(breakpoint, target);
            }

            this.dispatchEventToListeners(WI.DOMDebuggerManager.Event.DOMBreakpointAdded, {breakpoint});

            WI.debuggerManager.addProbesForBreakpoint(breakpoint);
        } else
            this._speculativelyResolveDOMBreakpoint(breakpoint);

        if (!this._restoringBreakpoints)
            WI.objectStores.domBreakpoints.putObject(breakpoint);
    }

    removeDOMBreakpoint(breakpoint)
    {
        console.assert(breakpoint instanceof WI.DOMBreakpoint, breakpoint);
        console.assert(breakpoint.url, breakpoint);
        if (!breakpoint || !breakpoint.url)
            return;

        console.assert(!breakpoint.special, breakpoint);

        // Disable the breakpoint first, so removing actions doesn't re-add the breakpoint.
        breakpoint.disabled = true;
        breakpoint.clearActions();

        this._domBreakpointURLMap.delete(breakpoint.url);

        if (breakpoint.domNode) {
            if (breakpoint.domNode.frame) {
                let domBreakpointNodeIdentifierMap = this._domBreakpointFrameIdentifierMap.get(breakpoint.domNode.frame);
                domBreakpointNodeIdentifierMap.delete(breakpoint.domNode, breakpoint);
                if (!domBreakpointNodeIdentifierMap.size)
                    this._domBreakpointFrameIdentifierMap.delete(breakpoint.domNode.frame);
            }

            this.dispatchEventToListeners(WI.DOMDebuggerManager.Event.DOMBreakpointRemoved, {breakpoint});

            breakpoint.domNode = null;
        }

        if (!this._restoringBreakpoints)
            WI.objectStores.domBreakpoints.deleteObject(breakpoint);
    }

    removeDOMBreakpointsForNode(node)
    {
        this.domBreakpointsForNode(node).forEach(this.removeDOMBreakpoint, this);
    }

    listenerBreakpointForEventName(eventName)
    {
        if (DOMDebuggerManager.supportsAllListenersBreakpoint() && this._allListenersBreakpoint && !this._allListenersBreakpoint.disabled)
            return this._allListenersBreakpoint;
        return this._listenerBreakpoints.find((breakpoint) => breakpoint.eventName === eventName) || null;
    }

    addEventBreakpoint(breakpoint)
    {
        console.assert(breakpoint instanceof WI.EventBreakpoint, breakpoint);
        if (!breakpoint)
            return false;

        console.assert(!breakpoint.special, breakpoint);

        switch (breakpoint.type) {
        case WI.EventBreakpoint.Type.AnimationFrame:
            console.assert(!this._allAnimationFramesBreakpoint, this._allAnimationFramesBreakpoint, breakpoint);
            this._allAnimationFramesBreakpoint = breakpoint;
            break;

        case WI.EventBreakpoint.Type.Interval:
            console.assert(!this._allIntervalsBreakpoint, this._allIntervalsBreakpoint, breakpoint);
            this._allIntervalsBreakpoint = breakpoint;
            break;

        case WI.EventBreakpoint.Type.Listener:
            if (breakpoint.eventName) {
                if (this._listenerBreakpoints.find((existing) => existing.eventName === breakpoint.eventName))
                    return false;

                this._listenerBreakpoints.push(breakpoint);
            } else {
                console.assert(!this._allListenersBreakpoint, this._allListenersBreakpoint, breakpoint);
                this._allListenersBreakpoint = breakpoint;
            }
            break;

        case WI.EventBreakpoint.Type.Timeout:
            console.assert(!this._allTimeoutsBreakpoint, this._allTimeoutsBreakpoint, breakpoint);
            this._allTimeoutsBreakpoint = breakpoint;
            break;
        }

        WI.debuggerManager.addProbesForBreakpoint(breakpoint);

        this.dispatchEventToListeners(WI.DOMDebuggerManager.Event.EventBreakpointAdded, {breakpoint});

        if (!breakpoint.disabled) {
            for (let target of WI.targets)
                this._setEventBreakpoint(breakpoint, target);
        }

        if (!this._restoringBreakpoints)
            WI.objectStores.eventBreakpoints.putObject(breakpoint);

        return true;
    }

    removeEventBreakpoint(breakpoint)
    {
        console.assert(breakpoint instanceof WI.EventBreakpoint, breakpoint);
        if (!breakpoint)
            return;

        // Disable the breakpoint first, so removing actions doesn't re-add the breakpoint.
        breakpoint.disabled = true;
        breakpoint.clearActions();

        switch (breakpoint.type) {
        case WI.EventBreakpoint.Type.AnimationFrame:
            console.assert(this._allAnimationFramesBreakpoint, this._allAnimationFramesBreakpoint);
            this._allAnimationFramesBreakpoint = null;
            break;

        case WI.EventBreakpoint.Type.Interval:
            console.assert(this._allIntervalsBreakpoint, this._allIntervalsBreakpoint);
            this._allIntervalsBreakpoint = null;
            break;

        case WI.EventBreakpoint.Type.Listener:
            if (breakpoint.eventName) {
                console.assert(this._listenerBreakpoints.includes(breakpoint), breakpoint);
                if (!this._listenerBreakpoints.includes(breakpoint))
                    return;

                this._listenerBreakpoints.remove(breakpoint);
            } else {
                console.assert(this._allListenersBreakpoint, this._allListenersBreakpoint);
                this._allListenersBreakpoint = null;
            }
            break;

        case WI.EventBreakpoint.Type.Timeout:
            console.assert(this._allTimeoutsBreakpoint, this._allTimeoutsBreakpoint);
            this._allTimeoutsBreakpoint = null;
            break;
        }

        if (!this._restoringBreakpoints)
            WI.objectStores.eventBreakpoints.deleteObject(breakpoint);

        WI.debuggerManager.removeProbesForBreakpoint(breakpoint);

        this.dispatchEventToListeners(WI.DOMDebuggerManager.Event.EventBreakpointRemoved, {breakpoint});
    }

    urlBreakpointForURL(url)
    {
        return this._urlBreakpoints.find((breakpoint) => breakpoint.url === url) || null;
    }

    urlBreakpointsMatchingURL(url)
    {
        return this._urlBreakpoints
            .filter((urlBreakpoint) => {
                switch (urlBreakpoint.type) {
                case WI.URLBreakpoint.Type.Text:
                    return urlBreakpoint.url.toLowerCase() === url.toLowerCase();

                case WI.URLBreakpoint.Type.RegularExpression:
                    return (new RegExp(urlBreakpoint.url, "i")).test(url);
                }

                return false;
            })
            .sort((a, b) => {
                // Order URL breakpoints based on how closely they match the given URL.
                const typeRankings = [
                    WI.URLBreakpoint.Type.Text,
                    WI.URLBreakpoint.Type.RegularExpression,
                ];
                return typeRankings.indexOf(a.type) - typeRankings.indexOf(b.type);
            });
    }

    addURLBreakpoint(breakpoint)
    {
        console.assert(breakpoint instanceof WI.URLBreakpoint, breakpoint);
        if (!breakpoint)
            return false;

        console.assert(!breakpoint.special, breakpoint);
        if (breakpoint.url) {
            if (this._urlBreakpoints.some((entry) => entry.type === breakpoint.type && entry.url === breakpoint.url))
                return false;

            this._urlBreakpoints.push(breakpoint);
        } else {
            console.assert(!this._allRequestsBreakpoint, this._allRequestsBreakpoint, breakpoint);
            this._allRequestsBreakpoint = breakpoint;
        }

        WI.debuggerManager.addProbesForBreakpoint(breakpoint);

        this.dispatchEventToListeners(WI.DOMDebuggerManager.Event.URLBreakpointAdded, {breakpoint});

        if (!breakpoint.disabled) {
            for (let target of WI.targets)
                this._setURLBreakpoint(breakpoint, target);
        }

        if (!this._restoringBreakpoints)
            WI.objectStores.urlBreakpoints.putObject(breakpoint);

        return true;
    }

    removeURLBreakpoint(breakpoint)
    {
        console.assert(breakpoint instanceof WI.URLBreakpoint, breakpoint);
        if (!breakpoint)
            return;

        // Disable the breakpoint first, so removing actions doesn't re-add the breakpoint.
        breakpoint.disabled = true;
        breakpoint.clearActions();

        if (breakpoint.url) {
            console.assert(this._urlBreakpoints.includes(breakpoint), breakpoint);
            if (!this._urlBreakpoints.includes(breakpoint))
                return;

            this._urlBreakpoints.remove(breakpoint);
        } else {
            console.assert(this._allRequestsBreakpoint, this._allRequestsBreakpoint);
            this._allRequestsBreakpoint = null;
        }

        if (!this._restoringBreakpoints)
            WI.objectStores.urlBreakpoints.deleteObject(breakpoint);

        WI.debuggerManager.removeProbesForBreakpoint(breakpoint);

        this.dispatchEventToListeners(WI.DOMDebuggerManager.Event.URLBreakpointRemoved, {breakpoint});
    }

    // Private

    _detachDOMBreakpointsForFrame(frame)
    {
        let domBreakpointNodeIdentifierMap = this._domBreakpointFrameIdentifierMap.get(frame);
        if (domBreakpointNodeIdentifierMap) {
            this._domBreakpointFrameIdentifierMap.delete(frame);

            this._clearingDOMBreakpointsForRemovedDOMNode = true;
            for (let breakpoint of domBreakpointNodeIdentifierMap.values())
                breakpoint.domNode = null;
            this._clearingDOMBreakpointsForRemovedDOMNode = false;
        }

        for (let childFrame of frame.childFrameCollection)
            this._detachDOMBreakpointsForFrame(childFrame);
    }

    _speculativelyResolveDOMBreakpointsForURL(url)
    {
        let domBreakpoints = this._domBreakpointURLMap.get(url);
        if (!domBreakpoints)
            return;

        for (let breakpoint of domBreakpoints)
            this._speculativelyResolveDOMBreakpoint(breakpoint);
    }

    _speculativelyResolveDOMBreakpoint(breakpoint)
    {
        if (breakpoint.domNode)
            return;

        WI.domManager.pushNodeByPathToFrontend(breakpoint.path, (nodeIdentifier) => {
            if (!nodeIdentifier)
                return;

            if (breakpoint.domNode) {
                // This breakpoint may have been resolved by a node being inserted before this
                // callback is invoked.  If so, the `nodeIdentifier` should match, so don't try
                // to resolve it again as it would've already been resolved.
                console.assert(breakpoint.domNode.id === nodeIdentifier);
                return;
            }

            this._restoringBreakpoints = true;
            this._resolveDOMBreakpoint(breakpoint, WI.domManager.nodeForId(nodeIdentifier));
            this._restoringBreakpoints = false;
        });
    }

    _resolveDOMBreakpoint(breakpoint, node)
    {
        console.assert(node instanceof WI.DOMNode, node);

        if (!node.frame)
            return;

        let domBreakpointNodeIdentifierMap = this._domBreakpointFrameIdentifierMap.get(node.frame);
        if (!domBreakpointNodeIdentifierMap) {
            domBreakpointNodeIdentifierMap = new Multimap;
            this._domBreakpointFrameIdentifierMap.set(node.frame, domBreakpointNodeIdentifierMap);
        }

        domBreakpointNodeIdentifierMap.add(node, breakpoint);

        breakpoint.domNode = node;
    }

    _setDOMBreakpoint(breakpoint, target)
    {
        console.assert(!breakpoint.disabled, breakpoint);
        console.assert(breakpoint.domNode instanceof WI.DOMNode, breakpoint);
        console.assert(target.type !== WI.TargetType.Worker, "Worker targets do not support DOM breakpoints", target);

        // COMPATIBILITY (iOS 10.3): DOMDebugger.setDOMBreakpoint did not exist yet.
        if (!target.hasCommand("DOMDebugger.setDOMBreakpoint"))
            return;

        if (!this._restoringBreakpoints && !WI.debuggerManager.breakpointsDisabledTemporarily)
            WI.debuggerManager.breakpointsEnabled = true;

        target.DOMDebuggerAgent.setDOMBreakpoint.invoke({
            nodeId: breakpoint.domNode.id,
            type: breakpoint.type,
            options: breakpoint.optionsToProtocol(),
        });
    }

    _removeDOMBreakpoint(breakpoint, target)
    {
        console.assert(breakpoint.domNode instanceof WI.DOMNode, breakpoint);
        console.assert(target.type !== WI.TargetType.Worker, "Worker targets do not support DOM breakpoints", target);

        // COMPATIBILITY (iOS 10.3): DOMDebugger.removeDOMBreakpoint did not exist yet.
        if (!target.hasCommand("DOMDebugger.removeDOMBreakpoint"))
            return;

        target.DOMDebuggerAgent.removeDOMBreakpoint(breakpoint.domNode.id, breakpoint.type);
    }

    _commandArgumentsForEventBreakpoint(breakpoint)
    {
        let commandArguments = {};

        switch (breakpoint) {
        case this._allAnimationFramesBreakpoint:
            commandArguments.breakpointType = WI.EventBreakpoint.Type.AnimationFrame;
            if (!DOMDebuggerManager.supportsAllListenersBreakpoint())
                commandArguments.eventName = "requestAnimationFrame";
            break;

        case this._allIntervalsBreakpoint:
            if (DOMDebuggerManager.supportsAllListenersBreakpoint())
                commandArguments.breakpointType = WI.EventBreakpoint.Type.Interval;
            else {
                commandArguments.breakpointType = WI.EventBreakpoint.Type.Timer;
                commandArguments.eventName = "setInterval";
            }
            break;

        case this._allListenersBreakpoint:
            if (!DOMDebuggerManager.supportsAllListenersBreakpoint())
                return;

            commandArguments.breakpointType = WI.EventBreakpoint.Type.Listener;
            break;

        case this._allTimeoutsBreakpoint:
            if (DOMDebuggerManager.supportsAllListenersBreakpoint())
                commandArguments.breakpointType = WI.EventBreakpoint.Type.Timeout;
            else {
                commandArguments.breakpointType = WI.EventBreakpoint.Type.Timer;
                commandArguments.eventName = "setTimeout";
            }
            break;

        default:
            commandArguments.breakpointType = breakpoint.type;
            commandArguments.eventName = breakpoint.eventName;
            console.assert(commandArguments.eventName);
            break;
        }

        return commandArguments;
    }

    _setEventBreakpoint(breakpoint, target)
    {
        console.assert(!breakpoint.disabled, breakpoint);

        // Worker targets do not support `requestAnimationFrame` breakpoints.
        if (breakpoint === this._allAnimationFramesBreakpoint && target.type === WI.TargetType.Worker)
            return;

        // COMPATIBILITY (iOS 10.3): DOMDebugger.setEventListenerBreakpoint did not exist yet.
        // COMPATIBILITY (iOS 12.0): DOMDebugger.setEventListenerBreakpoint was replaced by DOMDebugger.setEventBreakpoint.
        if (target.hasCommand("DOMDebugger.setEventListenerBreakpoint")) {
            console.assert(breakpoint.type === WI.EventBreakpoint.Type.Listener);

            if (!this._restoringBreakpoints && !WI.debuggerManager.breakpointsDisabledTemporarily)
                WI.debuggerManager.breakpointsEnabled = true;

            target.DOMDebuggerAgent.setEventListenerBreakpoint(breakpoint.eventName);
            return;
        }

        // COMPATIBILITY (iOS 12.0): DOMDebugger.setEventBreakpoint did not exist yet.
        if (!target.hasCommand("DOMDebugger.setEventBreakpoint"))
            return;

        let commandArguments = this._commandArgumentsForEventBreakpoint(breakpoint);

        if (!this._restoringBreakpoints && !WI.debuggerManager.breakpointsDisabledTemporarily)
            WI.debuggerManager.breakpointsEnabled = true;

        commandArguments.options = breakpoint.optionsToProtocol();

        target.DOMDebuggerAgent.setEventBreakpoint.invoke(commandArguments);
    }

    _removeEventBreakpoint(breakpoint, target)
    {
        // Worker targets do not support `requestAnimationFrame` breakpoints.
        if (breakpoint === this._allAnimationFramesBreakpoint && target.type === WI.TargetType.Worker)
            return;

        // COMPATIBILITY (iOS 10.3): DOMDebugger.removeEventListenerBreakpoint did not exist yet.
        // COMPATIBILITY (iOS 12.0): DOMDebugger.removeEventListenerBreakpoint was replaced by DOMDebugger.removeEventBreakpoint.
        if (target.hasCommand("DOMDebugger.removeEventListenerBreakpoint")) {
            console.assert(breakpoint.type === WI.EventBreakpoint.Type.Listener);
            target.DOMDebuggerAgent.removeEventListenerBreakpoint(breakpoint.eventName);
            return;
        }

        // COMPATIBILITY (iOS 12.0): DOMDebugger.removeEventBreakpoint did not exist yet.
        if (!target.hasCommand("DOMDebugger.removeEventBreakpoint"))
            return;

        let commandArguments = this._commandArgumentsForEventBreakpoint(breakpoint);

        target.DOMDebuggerAgent.removeEventBreakpoint.invoke(commandArguments);
    }

    _setURLBreakpoint(breakpoint, target)
    {
        console.assert(!breakpoint.disabled, breakpoint);

        // COMPATIBILITY (iOS 10.3): DOMDebugger.setXHRBreakpoint did not exist yet.
        // COMPATIBILITY (iOS 12.2): DOMDebugger.setXHRBreakpoint was replaced by DOMDebugger.setURLBreakpoint.
        if (target.hasCommand("DOMDebugger.setXHRBreakpoint")) {
            if (!this._restoringBreakpoints && !WI.debuggerManager.breakpointsDisabledTemporarily)
                WI.debuggerManager.breakpointsEnabled = true;

            let isRegex = breakpoint.type === WI.URLBreakpoint.Type.RegularExpression;
            target.DOMDebuggerAgent.setXHRBreakpoint(breakpoint.url, isRegex);
            return;
        }

        // COMPATIBILITY (iOS 12.2): DOMDebugger.setURLBreakpoint did not exist yet.
        if (!target.hasCommand("DOMDebugger.setURLBreakpoint"))
            return;

        if (!this._restoringBreakpoints && !WI.debuggerManager.breakpointsDisabledTemporarily)
            WI.debuggerManager.breakpointsEnabled = true;

        target.DOMDebuggerAgent.setURLBreakpoint.invoke({
            url: breakpoint.url,
            isRegex: breakpoint.type === WI.URLBreakpoint.Type.RegularExpression,
            options: breakpoint.optionsToProtocol(),
        });
    }

    _removeURLBreakpoint(breakpoint, target)
    {
        // COMPATIBILITY (iOS 10.3): DOMDebugger.removeXHRBreakpoint did not exist yet.
        // COMPATIBILITY (iOS 12.2): DOMDebugger.removeXHRBreakpoint was replaced by DOMDebugger.setURLBreakpoint.
        if (target.hasCommand("DOMDebugger.removeXHRBreakpoint")) {
            target.DOMDebuggerAgent.removeXHRBreakpoint(breakpoint.url);
            return;
        }

        // COMPATIBILITY (iOS 12.2): DOMDebugger.removeURLBreakpoint did not exist yet.
        if (!target.hasCommand("DOMDebugger.removeURLBreakpoint"))
            return;

        target.DOMDebuggerAgent.removeURLBreakpoint.invoke({
            url: breakpoint.url,
            isRegex: breakpoint.type === WI.URLBreakpoint.Type.RegularExpression,
        });
    }

    _handleDOMBreakpointDisabledStateChanged(event)
    {
        let breakpoint = event.target;

        if (!this._restoringBreakpoints)
            WI.objectStores.domBreakpoints.putObject(breakpoint);

        if (!breakpoint.domNode)
            return;

        // We should get the target associated with the nodeIdentifier of this breakpoint.
        let target = WI.assumingMainTarget();
        if (target) {
            if (breakpoint.disabled)
                this._removeDOMBreakpoint(breakpoint, target);
            else
                this._setDOMBreakpoint(breakpoint, target);
        }
    }

    _handleDOMBreakpointEditablePropertyChanged(event)
    {
        let breakpoint = event.target;

        if (!this._restoringBreakpoints)
            WI.objectStores.domBreakpoints.putObject(breakpoint);

        if (!breakpoint.domNode)
            return;

        if (breakpoint.disabled)
            return;

        this._restoringBreakpoints = true;
        // We should get the target associated with the nodeIdentifier of this breakpoint.
        let target = WI.assumingMainTarget();
        if (target) {
            // Clear the old breakpoint from the backend before setting the new one.
            this._removeDOMBreakpoint(breakpoint, target);
            this._setDOMBreakpoint(breakpoint, target);
        }
        this._restoringBreakpoints = false;
    }

    _handleDOMBreakpointActionsChanged(event)
    {
        let breakpoint = event.target;

        this._handleDOMBreakpointEditablePropertyChanged(event);

        if (!breakpoint.domNode)
            return;

        WI.debuggerManager.updateProbesForBreakpoint(breakpoint);
    }

    _handleDOMBreakpointDOMNodeWillChange(event)
    {
        if (this._clearingDOMBreakpointsForRemovedDOMNode)
            return;

        let breakpoint = event.target;

        if (!breakpoint.domNode)
            return;

        if (!breakpoint.disabled) {
            // We should get the target associated with the nodeIdentifier of this breakpoint.
            let target = WI.assumingMainTarget();
            if (target)
                this._removeDOMBreakpoint(breakpoint, target);
        }

        WI.debuggerManager.removeProbesForBreakpoint(breakpoint);
    }

    _handleDOMBreakpointDOMNodeDidChange(event)
    {
        let breakpoint = event.target;

        if (!breakpoint.domNode)
            return;

        if (!breakpoint.disabled) {
            // We should get the target associated with the nodeIdentifier of this breakpoint.
            let target = WI.assumingMainTarget();
            if (target)
                this._setDOMBreakpoint(breakpoint, target);
        }

        WI.debuggerManager.addProbesForBreakpoint(breakpoint);
    }

    _handleEventBreakpointDisabledStateChanged(event)
    {
        let breakpoint = event.target;

        // Specific event listener breakpoints are handled by `DOMManager`.
        if (breakpoint.eventListener)
            return;

        for (let target of WI.targets) {
            if (breakpoint.disabled)
                this._removeEventBreakpoint(breakpoint, target);
            else
                this._setEventBreakpoint(breakpoint, target);
        }

        if (!this._restoringBreakpoints)
            WI.objectStores.eventBreakpoints.putObject(breakpoint);
    }

    _handleEventBreakpointEditablePropertyChanged(event)
    {
        let breakpoint = event.target;

        // Specific event listener breakpoints are handled by `DOMManager`.
        if (breakpoint.eventListener)
            return;

        if (!this._restoringBreakpoints)
            WI.objectStores.eventBreakpoints.putObject(breakpoint);

        if (breakpoint.disabled)
            return;

        this._restoringBreakpoints = true;
        for (let target of WI.targets) {
            // Clear the old breakpoint from the backend before setting the new one.
            this._removeEventBreakpoint(breakpoint, target);
            this._setEventBreakpoint(breakpoint, target);
        }
        this._restoringBreakpoints = false;
    }

    _handleEventBreakpointActionsChanged(event)
    {
        let breakpoint = event.target;

        // Specific event listener breakpoints are handled by `DOMManager`.
        if (breakpoint.eventListener)
            return;

        this._handleEventBreakpointEditablePropertyChanged(event);

        WI.debuggerManager.updateProbesForBreakpoint(breakpoint);
    }

    _handleURLBreakpointDisabledStateChanged(event)
    {
        let breakpoint = event.target;

        for (let target of WI.targets) {
            if (breakpoint.disabled)
                this._removeURLBreakpoint(breakpoint, target);
            else
                this._setURLBreakpoint(breakpoint, target);
        }

        if (!this._restoringBreakpoints)
            WI.objectStores.urlBreakpoints.putObject(breakpoint);
    }

    _handleURLBreakpointEditablePropertyChanged(event)
    {
        let breakpoint = event.target;

        if (!this._restoringBreakpoints)
            WI.objectStores.urlBreakpoints.putObject(breakpoint);

        if (breakpoint.disabled)
            return;

        this._restoringBreakpoints = true;
        for (let target of WI.targets) {
            // Clear the old breakpoint from the backend before setting the new one.
            this._removeURLBreakpoint(breakpoint, target)
            this._setURLBreakpoint(breakpoint, target);
        }
        this._restoringBreakpoints = false;
    }

    _handleURLBreakpointActionsChanged(event)
    {
        let breakpoint = event.target;

        this._handleURLBreakpointEditablePropertyChanged(event);

        WI.debuggerManager.updateProbesForBreakpoint(breakpoint);
    }

    _childFrameWasRemoved(event)
    {
        let frame = event.data.childFrame;
        this._detachDOMBreakpointsForFrame(frame);
    }

    _mainFrameDidChange(event)
    {
        this._speculativelyResolveDOMBreakpointsForURL(WI.networkManager.mainFrame.url);
    }

    _mainResourceDidChange(event)
    {
        let frame = event.target;
        if (frame.isMainFrame()) {
            this._clearingDOMBreakpointsForRemovedDOMNode = true;
            for (let breakpoint of this._domBreakpointURLMap.values())
                breakpoint.domNode = null;
            this._clearingDOMBreakpointsForRemovedDOMNode = false;

            this._domBreakpointFrameIdentifierMap.clear();
        } else
            this._detachDOMBreakpointsForFrame(frame);

        this._speculativelyResolveDOMBreakpointsForURL(frame.url);
    }

    _nodeInserted(event)
    {
        let node = event.data.node;
        if (node.nodeType() !== Node.ELEMENT_NODE || !node.frame)
            return;

        let url = node.frame.url;
        let breakpoints = this._domBreakpointURLMap.get(url);
        if (!breakpoints)
            return;

        let resolvableBreakpoints = [];
        for (let breakpoint of breakpoints) {
            if (!breakpoint.domNode)
                resolvableBreakpoints.push(breakpoint);
        }
        if (!resolvableBreakpoints.length)
            return;

        // This is not very expensive because `WI.DOMNode` children are lazily populated, so it's
        // unlikely that there will be a deep subtree to walk.
        let stack = [node];
        while (stack.length) {
            let child = stack.pop();
            let path = child.path();

            for (let i = resolvableBreakpoints.length - 1; i >= 0; --i) {
                if (resolvableBreakpoints[i].path === path) {
                    this._restoringBreakpoints = true;
                    this._resolveDOMBreakpoint(resolvableBreakpoints[i], child);
                    this._restoringBreakpoints = false;

                    resolvableBreakpoints.splice(i, 1);
                }
            }
            if (!resolvableBreakpoints.length)
                break;

            if (child.children?.length)
                stack.pushAll(child.children);
        }
    }

    _nodeRemoved(event)
    {
        let node = event.data.node;
        if (node.nodeType() !== Node.ELEMENT_NODE || !node.frame)
            return;

        let domBreakpointNodeIdentifierMap = this._domBreakpointFrameIdentifierMap.get(node.frame);
        if (!domBreakpointNodeIdentifierMap)
            return;

        for (let [breakpointOwner, breakpoints] of domBreakpointNodeIdentifierMap.sets()) {
            if (breakpointOwner == node || node.isAncestor(breakpointOwner)) {
                this._clearingDOMBreakpointsForRemovedDOMNode = true;
                for (let breakpoint of breakpoints)
                    breakpoint.domNode = null;
                this._clearingDOMBreakpointsForRemovedDOMNode = false;

                domBreakpointNodeIdentifierMap.delete(breakpointOwner);
                if (!domBreakpointNodeIdentifierMap.size) {
                    this._domBreakpointFrameIdentifierMap.delete(node.frame);
                    break;
                }
            }
        }
    }
};

WI.DOMDebuggerManager.Event = {
    DOMBreakpointAdded: "dom-debugger-manager-dom-breakpoint-added",
    DOMBreakpointRemoved: "dom-debugger-manager-dom-breakpoint-removed",
    EventBreakpointAdded: "dom-debugger-manager-event-breakpoint-added",
    EventBreakpointRemoved: "dom-debugger-manager-event-breakpoint-removed",
    URLBreakpointAdded: "dom-debugger-manager-url-breakpoint-added",
    URLBreakpointRemoved: "dom-debugger-manager-url-breakpoint-removed",
};
