/*
 * Copyright (C) 2013-2016 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.QuickConsole = class QuickConsole extends WI.View
{
    constructor(element)
    {
        super(element);

        this._toggleOrFocusKeyboardShortcut = new WI.KeyboardShortcut(null, WI.KeyboardShortcut.Key.Escape, this._toggleOrFocus.bind(this));
        this._toggleOrFocusKeyboardShortcut.implicitlyPreventsDefault = false;

        this._automaticExecutionContextPathComponent = this._createExecutionContextPathComponent(null, WI.UIString("Auto"));
        this._updateAutomaticExecutionContextPathComponentTooltip();

        this._mainExecutionContextPathComponent = null;
        this._otherExecutionContextPathComponents = [];

        this._frameToPathComponent = new Map;
        this._targetToPathComponent = new Map;

        this._shouldAutomaticallySelectExecutionContext = true;
        this._restoreSelectedExecutionContextForFrame = false;

        this.element.classList.add("quick-console");
        this.element.addEventListener("mousedown", this._handleMouseDown.bind(this));
        this.element.addEventListener("dragover", this._handleDragOver.bind(this));
        this.element.addEventListener("drop", this._handleDrop.bind(this), true); // Ensure that dropping a DOM node doesn't copy text.

        this.prompt = new WI.ConsolePrompt(null, "text/javascript");
        this.addSubview(this.prompt);

        // FIXME: CodeMirror 4 has a default "Esc" key handler that always prevents default.
        // Our keyboard shortcut above will respect the default prevented and ignore the event
        // and not toggle the console. Install our own Escape key handler that will trigger
        // when the ConsolePrompt is empty, to restore toggling behavior. A better solution
        // would be for CodeMirror's event handler to pass if it doesn't do anything.
        this.prompt.escapeKeyHandlerWhenEmpty = function() { WI.toggleSplitConsole(); };

        this._navigationBar = new WI.QuickConsoleNavigationBar;
        this.addSubview(this._navigationBar);

        this._executionContextSelectorItem = new WI.HierarchicalPathNavigationItem;
        this._executionContextSelectorItem.showSelectorArrows = true;
        this._navigationBar.addNavigationItem(this._executionContextSelectorItem);

        this._executionContextSelectorDivider = new WI.DividerNavigationItem;
        this._navigationBar.addNavigationItem(this._executionContextSelectorDivider);

        this.initializeMainExecutionContextPathComponent();

        WI.settings.consoleSavedResultAlias.addEventListener(WI.Setting.Event.Changed, this._updateAutomaticExecutionContextPathComponentTooltip, this);

        WI.consoleDrawer.toggleButtonShortcutTooltip(this._toggleOrFocusKeyboardShortcut);
        WI.consoleDrawer.addEventListener(WI.ConsoleDrawer.Event.CollapsedStateChanged, this._updateStyles, this);

        WI.Frame.addEventListener(WI.Frame.Event.PageExecutionContextChanged, this._framePageExecutionContextsChanged, this);
        WI.Frame.addEventListener(WI.Frame.Event.ExecutionContextsCleared, this._frameExecutionContextsCleared, this);

        WI.debuggerManager.addEventListener(WI.DebuggerManager.Event.ActiveCallFrameDidChange, this._debuggerActiveCallFrameDidChange, this);

        WI.runtimeManager.addEventListener(WI.RuntimeManager.Event.ActiveExecutionContextChanged, this._activeExecutionContextChanged, this);

        WI.targetManager.addEventListener(WI.TargetManager.Event.TargetAdded, this._targetAdded, this);
        WI.targetManager.addEventListener(WI.TargetManager.Event.TargetRemoved, this._targetRemoved, this);

        WI.domManager.addEventListener(WI.DOMManager.Event.InspectedNodeChanged, this._handleInspectedNodeChanged, this);

        WI.TabBrowser.addEventListener(WI.TabBrowser.Event.SelectedTabContentViewDidChange, this._updateStyles, this);
    }

    // Public

    get navigationBar()
    {
        return this._navigationBar;
    }

    closed()
    {
        WI.settings.consoleSavedResultAlias.removeEventListener(null, null, this);
        WI.Frame.removeEventListener(null, null, this);
        WI.debuggerManager.removeEventListener(null, null, this);
        WI.runtimeManager.removeEventListener(null, null, this);
        WI.targetManager.removeEventListener(null, null, this);
        WI.consoleDrawer.removeEventListener(null, null, this);
        WI.TabBrowser.removeEventListener(null, null, this);

        super.closed();
    }

    initializeMainExecutionContextPathComponent()
    {
        if (!WI.mainTarget || !WI.mainTarget.executionContext)
            return;

        this._mainExecutionContextPathComponent = this._createExecutionContextPathComponent(WI.mainTarget.executionContext);
        this._mainExecutionContextPathComponent.previousSibling = this._automaticExecutionContextPathComponent;

        this._automaticExecutionContextPathComponent.nextSibling = this._mainExecutionContextPathComponent;

        this._shouldAutomaticallySelectExecutionContext = true;
        this._selectExecutionContext(WI.mainTarget.executionContext);
        this._rebuildExecutionContextPathComponents();
    }

    // Protected

    layout()
    {
        // A hard maximum size of 33% of the window.
        let maximumAllowedHeight = Math.round(window.innerHeight * 0.33);
        this.prompt.element.style.maxHeight = maximumAllowedHeight + "px";
    }

    // Private

    _preferredNameForFrame(frame)
    {
        if (frame.name)
            return WI.UIString("%s (%s)").format(frame.name, frame.mainResource.displayName);
        return frame.mainResource.displayName;
    }

    _selectExecutionContext(executionContext)
    {
        let preferredName = null;

        let inspectedNode = WI.domManager.inspectedNode;
        if (inspectedNode) {
            let frame = inspectedNode.frame;
            if (frame) {
                if (this._shouldAutomaticallySelectExecutionContext)
                    executionContext = frame.pageExecutionContext;
                preferredName = this._preferredNameForFrame(frame);
            }
        }

        console.assert(executionContext);
        if (!executionContext)
            executionContext = WI.mainTarget.executionContext;

        this._automaticExecutionContextPathComponent.displayName = WI.UIString("Auto - %s").format(preferredName || executionContext.name);

        let changed = WI.runtimeManager.activeExecutionContext !== executionContext;
        if (changed)
            WI.runtimeManager.activeExecutionContext = executionContext;
        return changed;
    }

    _updateAutomaticExecutionContextPathComponentTooltip()
    {
        this._automaticExecutionContextPathComponent.tooltip = WI.UIString("Execution context for %s").format(WI.RuntimeManager.preferredSavedResultPrefix() + "0");
    }

    _handleMouseDown(event)
    {
        if (event.target !== this.element)
            return;

        event.preventDefault();
        this.prompt.focus();
    }

    _handleDragOver(event)
    {
        if (event.dataTransfer.types.includes(WI.DOMTreeOutline.DOMNodeIdDragType)) {
            event.preventDefault();
            event.dataTransfer.dropEffect = "copy";
        }
    }

    _handleDrop(event)
    {
        let domNodeId = event.dataTransfer.getData(WI.DOMTreeOutline.DOMNodeIdDragType);
        if (domNodeId) {
            event.preventDefault();

            let domNode = WI.domManager.nodeForId(domNodeId);
            WI.RemoteObject.resolveNode(domNode, WI.RuntimeManager.ConsoleObjectGroup)
            .then((remoteObject) => {
                let text = domNode.nodeType() === Node.ELEMENT_NODE ? WI.UIString("Dropped Element") : WI.UIString("Dropped Node");
                const addSpecialUserLogClass = true;
                WI.consoleLogViewController.appendImmediateExecutionWithResult(text, remoteObject, addSpecialUserLogClass);

                this.prompt.focus();
            });
        }
    }

    _executionContextPathComponentsToDisplay()
    {
        // If we are in the debugger the console will use the active call frame, don't show the selector.
        if (WI.debuggerManager.activeCallFrame)
            return [];

        // If there is only the Main ExecutionContext, don't show the selector.
        if (!this._otherExecutionContextPathComponents.length)
            return [];

        if (this._shouldAutomaticallySelectExecutionContext)
            return [this._automaticExecutionContextPathComponent];

        if (WI.runtimeManager.activeExecutionContext === WI.mainTarget.executionContext)
            return [this._mainExecutionContextPathComponent];

        return this._otherExecutionContextPathComponents.filter((component) => component.representedObject === WI.runtimeManager.activeExecutionContext);
    }

    _rebuildExecutionContextPathComponents()
    {
        let components = this._executionContextPathComponentsToDisplay();
        let isEmpty = !components.length;

        this._executionContextSelectorItem.element.classList.toggle("automatic-execution-context", this._shouldAutomaticallySelectExecutionContext);
        this._executionContextSelectorItem.components = components;

        this._executionContextSelectorItem.hidden = isEmpty;
        this._executionContextSelectorDivider.hidden = isEmpty;

    }

    _framePageExecutionContextsChanged(event)
    {
        let frame = event.target;

        let newExecutionContextPathComponent = this._insertExecutionContextPathComponentForFrame(frame);

        if (this._restoreSelectedExecutionContextForFrame === frame) {
            this._restoreSelectedExecutionContextForFrame = null;

            this._selectExecutionContext(newExecutionContextPathComponent.representedObject);
        }
    }

    _frameExecutionContextsCleared(event)
    {
        let frame = event.target;

        // If this frame is navigating and it is selected in the UI we want to reselect its new item after navigation.
        if (event.data.committingProvisionalLoad && !this._restoreSelectedExecutionContextForFrame) {
            let executionContextPathComponent = this._frameToPathComponent.get(frame);
            if (executionContextPathComponent && executionContextPathComponent.representedObject === WI.runtimeManager.activeExecutionContext) {
                this._restoreSelectedExecutionContextForFrame = frame;
                // As a fail safe, if the frame never gets an execution context, clear the restore value.
                setTimeout(() => {
                    this._restoreSelectedExecutionContextForFrame = false;
                }, 10);
            }
        }

        this._removeExecutionContextPathComponentForFrame(frame);
    }

    _activeExecutionContextChanged(event)
    {
        this._rebuildExecutionContextPathComponents();
    }

    _createExecutionContextPathComponent(executionContext, preferredName)
    {
        console.assert(!executionContext || executionContext instanceof WI.ExecutionContext);

        let pathComponent = new WI.HierarchicalPathComponent(preferredName || executionContext.name, "execution-context", executionContext, true, true);
        pathComponent.addEventListener(WI.HierarchicalPathComponent.Event.SiblingWasSelected, this._pathComponentSelected, this);
        pathComponent.addEventListener(WI.HierarchicalPathComponent.Event.Clicked, this._pathComponentClicked, this);
        pathComponent.truncatedDisplayNameLength = 50;
        return pathComponent;
    }

    _compareExecutionContextPathComponents(a, b)
    {
        let aExecutionContext = a.representedObject;
        let bExecutionContext = b.representedObject;

        // "Targets" (workers) at the top.
        let aNonMainTarget = aExecutionContext.target !== WI.mainTarget;
        let bNonMainTarget = bExecutionContext.target !== WI.mainTarget;
        if (aNonMainTarget && !bNonMainTarget)
            return -1;
        if (bNonMainTarget && !aNonMainTarget)
            return 1;
        if (aNonMainTarget && bNonMainTarget)
            return a.displayName.extendedLocaleCompare(b.displayName);

        // "Main Frame" follows.
        if (aExecutionContext === WI.mainTarget.executionContext)
            return -1;
        if (bExecutionContext === WI.mainTarget.executionContext)
            return 1;

        // Only Frame contexts remain.
        console.assert(aExecutionContext.frame);
        console.assert(bExecutionContext.frame);

        // Frames with a name above frames without a name.
        if (aExecutionContext.frame.name && !bExecutionContext.frame.name)
            return -1;
        if (!aExecutionContext.frame.name && bExecutionContext.frame.name)
            return 1;

        return a.displayName.extendedLocaleCompare(b.displayName);
    }

    _insertOtherExecutionContextPathComponent(executionContextPathComponent)
    {
        let index = insertionIndexForObjectInListSortedByFunction(executionContextPathComponent, this._otherExecutionContextPathComponents, this._compareExecutionContextPathComponents);

        let prev = index > 0 ? this._otherExecutionContextPathComponents[index - 1] : this._mainExecutionContextPathComponent;
        let next = this._otherExecutionContextPathComponents[index] || null;
        if (prev) {
            prev.nextSibling = executionContextPathComponent;
            executionContextPathComponent.previousSibling = prev;
        }
        if (next) {
            next.previousSibling = executionContextPathComponent;
            executionContextPathComponent.nextSibling = next;
        }

        this._otherExecutionContextPathComponents.splice(index, 0, executionContextPathComponent);

        this._rebuildExecutionContextPathComponents();
    }

    _removeOtherExecutionContextPathComponent(executionContextPathComponent)
    {
        executionContextPathComponent.removeEventListener(WI.HierarchicalPathComponent.Event.SiblingWasSelected, this._pathComponentSelected, this);
        executionContextPathComponent.removeEventListener(WI.HierarchicalPathComponent.Event.Clicked, this._pathComponentClicked, this);

        let prev = executionContextPathComponent.previousSibling;
        let next = executionContextPathComponent.nextSibling;
        if (prev)
            prev.nextSibling = next;
        if (next)
            next.previousSibling = prev;

        this._otherExecutionContextPathComponents.remove(executionContextPathComponent, true);

        this._rebuildExecutionContextPathComponents();
    }

    _insertExecutionContextPathComponentForFrame(frame)
    {
        if (frame.isMainFrame())
            return this._mainExecutionContextPathComponent;

        let executionContextPathComponent = this._createExecutionContextPathComponent(frame.pageExecutionContext, this._preferredNameForFrame(frame));
        this._insertOtherExecutionContextPathComponent(executionContextPathComponent);
        this._frameToPathComponent.set(frame, executionContextPathComponent);
        return executionContextPathComponent;
    }

    _removeExecutionContextPathComponentForFrame(frame)
    {
        if (frame.isMainFrame()) {
            this._shouldAutomaticallySelectExecutionContext = true;
            return;
        }

        let executionContextPathComponent = this._frameToPathComponent.take(frame);
        this._removeOtherExecutionContextPathComponent(executionContextPathComponent);
    }

    _targetAdded(event)
    {
        let target = event.data.target;
        if (target.type !== WI.Target.Type.Worker)
            return;

        console.assert(target.type === WI.Target.Type.Worker);
        let preferredName = WI.UIString("Worker \u2014 %s").format(target.displayName);
        let executionContextPathComponent = this._createExecutionContextPathComponent(target.executionContext, preferredName);

        this._targetToPathComponent.set(target, executionContextPathComponent);
        this._insertOtherExecutionContextPathComponent(executionContextPathComponent);
    }

    _targetRemoved(event)
    {
        let target = event.data.target;
        if (target.type !== WI.Target.Type.Worker)
            return;

        let executionContextPathComponent = this._targetToPathComponent.take(target);

        if (WI.runtimeManager.activeExecutionContext === executionContextPathComponent.representedObject) {
            this._shouldAutomaticallySelectExecutionContext = true;
            this._selectExecutionContext();
        }

        this._removeOtherExecutionContextPathComponent(executionContextPathComponent);
    }

    _pathComponentSelected(event)
    {
        this._shouldAutomaticallySelectExecutionContext = event.data.pathComponent === this._automaticExecutionContextPathComponent;

        // Only manually rebuild the execution context path components if the newly selected
        // execution context matches the previously selected one.
        if (!this._selectExecutionContext(event.data.pathComponent.representedObject))
            this._rebuildExecutionContextPathComponents();
    }

    _pathComponentClicked(event)
    {
        this.prompt.focus();
    }

    _debuggerActiveCallFrameDidChange(event)
    {
        this._rebuildExecutionContextPathComponents();
    }

    _toggleOrFocus(event)
    {
        if (this.prompt.focused) {
            WI.toggleSplitConsole();
            event.preventDefault();
        } else if (!WI.isEditingAnyField() && !WI.isEventTargetAnEditableField(event)) {
            this.prompt.focus();
            event.preventDefault();
        }
    }

    _updateStyles()
    {
        this.element.classList.toggle("showing-log", WI.isShowingConsoleTab() || WI.isShowingSplitConsole());
    }

    _handleInspectedNodeChanged(event)
    {
        this._selectExecutionContext(WI.runtimeManager.activeExecutionContext);
    }
};
