/*
 * Copyright (C) 2015 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.BreakpointPopover = class BreakpointPopover extends WI.Popover
{
    constructor(delegate, breakpoint)
    {
        console.assert(!breakpoint || breakpoint instanceof WI.Breakpoint, breakpoint);

        super(delegate);

        this._breakpoint = breakpoint || null;

        console.assert(this._breakpoint?.constructor.ReferencePage || this.constructor.ReferencePage, "Should have a link to a reference page.");

        this._contentElement = null;
        this._conditionCodeMirror = null;
        this._ignoreCountInputElement = null;
        this._actionsContainerElement = null;
        this._actionViews = [];
        this._optionsRowElement = null;
        this._autoContinueCheckboxElement = null;

        this._targetElement = null;

        this.windowResizeHandler = this._presentOverTargetElement.bind(this);
    }

    // Static

    static show(breakpoint, targetElement)
    {
        const delegate = null;
        let popover;
        if (breakpoint instanceof WI.EventBreakpoint)
            popover = new WI.EventBreakpointPopover(delegate, breakpoint);
        else if (breakpoint instanceof WI.URLBreakpoint)
            popover = new WI.URLBreakpointPopover(delegate, breakpoint);
        else
            popover = new WI.BreakpointPopover(delegate, breakpoint);
        popover.show(targetElement);
    }

    static appendContextMenuItems(contextMenu, breakpoint, targetElement)
    {
        if (breakpoint.editable && targetElement) {
            contextMenu.appendItem(WI.UIString("Edit Breakpoint\u2026"), () => {
                WI.BreakpointPopover.show(breakpoint, targetElement);
            });
        }

        if (!breakpoint.disabled) {
            contextMenu.appendItem(WI.UIString("Disable Breakpoint"), () => {
                breakpoint.disabled = !breakpoint.disabled;
            });

            if (breakpoint.editable && breakpoint.autoContinue) {
                contextMenu.appendItem(WI.UIString("Cancel Automatic Continue"), () => {
                    breakpoint.autoContinue = !breakpoint.autoContinue;
                });
            }
        } else {
            contextMenu.appendItem(WI.UIString("Enable Breakpoint"), () => {
                breakpoint.disabled = !breakpoint.disabled;
            });
        }

        if (breakpoint.editable && !breakpoint.autoContinue && !breakpoint.disabled && breakpoint.actions.length) {
            contextMenu.appendItem(WI.UIString("Set to Automatically Continue"), () => {
                breakpoint.autoContinue = !breakpoint.autoContinue;
            });
        }

        if (breakpoint.removable) {
            contextMenu.appendItem(WI.UIString("Delete Breakpoint"), () => {
                breakpoint.remove();
            });
        } else {
            contextMenu.appendItem(WI.UIString("Reset Breakpoint", "Reset Breakpoint @ Breakpoint Context Menu", "Context menu action for resetting the breakpoint to its initial configuration."), () => {
                breakpoint.reset();
            });
        }

        if (breakpoint instanceof WI.JavaScriptBreakpoint && breakpoint.sourceCodeLocation.hasMappedLocation()) {
            contextMenu.appendSeparator();
            contextMenu.appendItem(WI.UIString("Reveal in Original Resource"), () => {
                const options = {
                    ignoreNetworkTab: true,
                    ignoreSearchTab: true,
                };
                WI.showOriginalOrFormattedSourceCodeLocation(breakpoint.sourceCodeLocation, options);
            });
        }
    }

    // Public

    get breakpoint() { return this._breakpoint; }

    show(targetElement)
    {
        this._targetElement = targetElement;

        this._contentElement = document.createElement("div");
        this._contentElement.classList.add("edit-breakpoint-popover-content");

        if (this._breakpoint) {
            let toggleLabelElement = this._contentElement.appendChild(document.createElement("label"));
            toggleLabelElement.className = "toggle";

            let toggleCheckboxElement = toggleLabelElement.appendChild(document.createElement("input"));
            toggleCheckboxElement.type = "checkbox";
            toggleCheckboxElement.checked = !this._breakpoint.disabled;
            toggleCheckboxElement.addEventListener("change", this._handleEnabledCheckboxChange.bind(this));

            toggleLabelElement.appendChild(document.createTextNode(this._breakpoint.displayName));
        }

        this._tableElement = this._contentElement.appendChild(document.createElement("table"));

        if (!this._breakpoint)
            this.populateContent();

        if (this._breakpoint?.editable || this.constructor.supportsEditing) {
            let conditionLabelElement = document.createElement("label");
            conditionLabelElement.textContent = WI.UIString("Condition");

            let conditionEditorElement = document.createElement("div");
            conditionEditorElement.classList.add("editor", WI.SyntaxHighlightedStyleClassName);

            this._conditionCodeMirror = WI.CodeMirrorEditor.create(conditionEditorElement, {
                extraKeys: {Tab: false},
                lineWrapping: false,
                mode: "text/javascript",
                matchBrackets: true,
                placeholder: WI.UIString("Conditional expression"),
                scrollbarStyle: null,
                value: this._breakpoint?.condition || "",
            });

            let conditionCodeMirrorInputField = this._conditionCodeMirror.getInputField();
            conditionCodeMirrorInputField.id = "edit-breakpoint-popover-content-condition";
            conditionLabelElement.setAttribute("for", conditionCodeMirrorInputField.id);

            this.addRow("condition", conditionLabelElement, conditionEditorElement);

            this._conditionCodeMirror.addKeyMap({
                "Enter": () => { this.dismiss(); },
                "Esc": () => { this.dismiss(); },
            });

            this._conditionCodeMirror.on("beforeChange", this._handleConditionCodeMirrorBeforeChange.bind(this));
            if (this._breakpoint)
                this._conditionCodeMirror.on("change", this._handleConditionCodeMirrorChange.bind(this));

            let completionController = new WI.CodeMirrorCompletionController(this.codeMirrorCompletionControllerMode, this._conditionCodeMirror, this);
            completionController.addExtendedCompletionProvider("javascript", WI.javaScriptRuntimeCompletionProvider);

            let ignoreCountLabelElement = document.createElement("label");
            ignoreCountLabelElement.textContent = WI.UIString("Ignore");

            let ignoreCountContentFragment = document.createDocumentFragment();

            this._ignoreCountInputElement = ignoreCountContentFragment.appendChild(document.createElement("input"));
            this._ignoreCountInputElement.id = "edit-breakpoint-popover-ignore-count";
            this._ignoreCountInputElement.type = "number";
            this._ignoreCountInputElement.min = 0;
            this._ignoreCountInputElement.value = this._breakpoint?.ignoreCount || 0;
            this._ignoreCountInputElement.addEventListener("change", this._handleIgnoreCountInputChange.bind(this));

            this._ignoreCountText = ignoreCountContentFragment.appendChild(document.createElement("label"));
            this._updateIgnoreCountText();

            ignoreCountLabelElement.setAttribute("for", this._ignoreCountInputElement.id);
            this._ignoreCountText.setAttribute("for", this._ignoreCountInputElement.id);

            this.addRow("ignore-count", ignoreCountLabelElement, ignoreCountContentFragment);

            let actionsLabelElement = document.createElement("label");
            actionsLabelElement.textContent = WI.UIString("Action");

            this._actionsContainerElement = document.createElement("div");

            if (!this._breakpoint?.actions.length)
                this._createAddActionButton();
            else {
                this._contentElement.classList.add("wide");

                for (let i = 0; i < this._breakpoint.actions.length; ++i) {
                    let breakpointActionView = new WI.BreakpointActionView(this._breakpoint.actions[i], this, {omitFocus: true});
                    this._insertBreakpointActionView(breakpointActionView);
                }
            }

            this.addRow("actions", actionsLabelElement, this._actionsContainerElement);

            let optionsLabelElement = document.createElement("label");
            optionsLabelElement.textContent = WI.UIString("Options");

            let optionsDocumentFragment = document.createDocumentFragment();

            this._autoContinueCheckboxElement = optionsDocumentFragment.appendChild(document.createElement("input"));
            this._autoContinueCheckboxElement.id = "edit-breakpoint-popover-auto-continue";
            this._autoContinueCheckboxElement.type = "checkbox";
            this._autoContinueCheckboxElement.checked = this._breakpoint?.autoContinue || false;
            this._autoContinueCheckboxElement.addEventListener("change", this._handleAutoContinueCheckboxChange.bind(this));

            let optionsCheckboxLabel = optionsDocumentFragment.appendChild(document.createElement("label"));
            optionsCheckboxLabel.textContent = WI.UIString("Automatically continue after evaluating");

            optionsLabelElement.setAttribute("for", this._autoContinueCheckboxElement.id);
            optionsCheckboxLabel.setAttribute("for", this._autoContinueCheckboxElement.id);

            this._optionsRowElement = this.addRow("options", optionsLabelElement, optionsDocumentFragment);
            if (!this._breakpoint?.actions.length)
                this._optionsRowElement.classList.add("hidden");

            // CodeMirror needs to refresh after the popover is shown as otherwise it doesn't appear.
            setTimeout(() => {
                this._conditionCodeMirror.refresh();
                if (this._breakpoint)
                    this._conditionCodeMirror.focus();

                this.update();
            });
        }

        let referencePage = this._breakpoint?.constructor.ReferencePage || this.constructor.ReferencePage;
        if (this._breakpoint)
            referencePage = referencePage.Configuration;
        this._contentElement.appendChild(referencePage.createLinkElement());

        this.content = this._contentElement;

        this._presentOverTargetElement();
    }

    dismiss()
    {
        this._breakpoint ??= this.createBreakpoint({
            condition: this._conditionCodeMirror ? this._conditionCodeMirror.getValue().trim() : "",
            actions: this._actionViews.map((breakpointActionView) => breakpointActionView.action),
            ignoreCount: this._ignoreCountInputElement ? this._parseIgnoreCountNumber() : 0,
            autoContinue: this._autoContinueCheckboxElement ? this._autoContinueCheckboxElement.checked : false,
        });

        // Remove Evaluate and Probe actions that have no data.
        let emptyActions = this._breakpoint?.actions.filter(function(action) {
            if (action.type === WI.BreakpointAction.Type.Sound)
                return false;
            return !action.data?.trim();
        }) || [];
        for (let action of emptyActions)
            this._breakpoint.removeAction(action);

        super.dismiss();
    }

    // CodeMirrorCompletionController delegate

    completionControllerShouldAllowEscapeCompletion()
    {
        return false;
    }

    // BreakpointActionView delegate

    breakpointActionViewCodeMirrorCompletionControllerMode(breakpointActionView, codeMirror)
    {
        return this.codeMirrorCompletionControllerMode;
    }

    breakpointActionViewAppendActionView(breakpointActionView, newBreakpointAction)
    {
        this._breakpoint?.addAction(newBreakpointAction, {precedingAction: breakpointActionView.action});

        let newBreakpointActionView = new WI.BreakpointActionView(newBreakpointAction, this);

        let index = this._actionViews.indexOf(breakpointActionView) + 1;
        this._insertBreakpointActionView(newBreakpointActionView, index);
        this._optionsRowElement.classList.remove("hidden");

        this.update();
    }

    breakpointActionViewRemoveActionView(breakpointActionView)
    {
        this._breakpoint?.removeAction(breakpointActionView.action);

        breakpointActionView.element.remove();
        this._actionViews.remove(breakpointActionView);

        if (!this._actionViews.length) {
            this._createAddActionButton();
            this._optionsRowElement.classList.add("hidden");
            this._autoContinueCheckboxElement.checked = false;
        }

        this.update();
    }

    breakpointActionViewResized(breakpointActionView)
    {
        this.update();
    }

    // Protected

    get codeMirrorCompletionControllerMode()
    {
        // Overridden by subclasses if needed.

        if (this._breakpoint === WI.debuggerManager.allExceptionsBreakpoint || this._breakpoint === WI.debuggerManager.uncaughtExceptionsBreakpoint)
            return WI.CodeMirrorCompletionController.Mode.ExceptionBreakpoint;

        return WI.CodeMirrorCompletionController.Mode.Basic;
    }

    populateContent()
    {
        throw WI.NotImplementedError.subclassMustOverride();
    }

    addRow(className, label, content)
    {
        let rowElement = this._tableElement.appendChild(document.createElement("tr"));
        rowElement.className = className;

        let headerElement = rowElement.appendChild(document.createElement("th"));
        headerElement.append(label);

        let dataElement = rowElement.appendChild(document.createElement("td"));
        dataElement.append(content);

        return rowElement;
    }

    createBreakpoint(options = {})
    {
        throw WI.NotImplementedError.subclassMustOverride();
    }

    // Private

    _presentOverTargetElement()
    {
        if (!this._targetElement)
            return;

        let targetFrame = WI.Rect.rectFromClientRect(this._targetElement.getBoundingClientRect());
        this.present(targetFrame.pad(2), [WI.RectEdge.MAX_Y, WI.RectEdge.MIN_Y, WI.RectEdge.MAX_X]);
    }

    _parseIgnoreCountNumber()
    {
        let ignoreCount = 0;
        if (this._ignoreCountInputElement.value) {
            ignoreCount = parseInt(this._ignoreCountInputElement.value, 10);
            if (isNaN(ignoreCount) || ignoreCount < 0)
                ignoreCount = 0;
        }
        return ignoreCount;
    }

    _updateIgnoreCountText()
    {
        if (this._parseIgnoreCountNumber() === 1)
            this._ignoreCountText.textContent = WI.UIString("time before stopping");
        else
            this._ignoreCountText.textContent = WI.UIString("times before stopping");
    }

    _createAddActionButton()
    {
        this._contentElement.classList.remove("wide");
        this._actionsContainerElement.removeChildren();

        let addActionButton = this._actionsContainerElement.appendChild(document.createElement("button"));
        addActionButton.textContent = WI.UIString("Add Action");
        addActionButton.addEventListener("click", this._handleAddActionButtonClick.bind(this));
    }

    _insertBreakpointActionView(breakpointActionView, index = this._actionViews.length)
    {
        if (index >= this._actionViews.length) {
            this._actionsContainerElement.appendChild(breakpointActionView.element);
            this._actionViews.push(breakpointActionView);
        } else {
            this._actionsContainerElement.insertBefore(breakpointActionView.element, this._actionViews[index].element);
            this._actionViews.splice(index, 0, breakpointActionView)
        }
    }

    _handleEnabledCheckboxChange(event)
    {
        this._breakpoint.disabled = !event.target.checked;
    }

    _handleConditionCodeMirrorBeforeChange(codeMirror, change)
    {
        if (change.update) {
            let newText = change.text.join("").replace(/\n/g, "");
            change.update(change.from, change.to, [newText]);
        }

        return true;
    }

    _handleConditionCodeMirrorChange(codeMirror, change)
    {
        this._breakpoint.condition = this._conditionCodeMirror.getValue().trim();
    }

    _handleIgnoreCountInputChange(event)
    {
        let ignoreCount = this._parseIgnoreCountNumber();
        this._ignoreCountInputElement.value = ignoreCount;

        if (this._breakpoint)
            this._breakpoint.ignoreCount = ignoreCount;

        this._updateIgnoreCountText();
    }

    _handleAddActionButtonClick(event)
    {
        this._contentElement.classList.add("wide");

        this._actionsContainerElement.removeChildren();

        let action = new WI.BreakpointAction(WI.BreakpointAction.Type.Evaluate);
        this._breakpoint?.addAction(action);

        let breakpointActionView = new WI.BreakpointActionView(action, this);
        this._insertBreakpointActionView(breakpointActionView);

        this._optionsRowElement.classList.remove("hidden");

        this.update();
    }

    _handleAutoContinueCheckboxChange(event)
    {
        if (this._breakpoint)
            this._breakpoint.autoContinue = this._autoContinueCheckboxElement.checked;
    }
};
