/*
 * Copyright (C) 2013-2021 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.ContentView = class ContentView extends WI.View
{
    constructor(representedObject, extraArguments)
    {
        // Concrete object instantiation.
        console.assert(!representedObject || WI.ContentView.isViewable(representedObject), representedObject);

        super();

        this._representedObject = representedObject;

        this.element.classList.add("content-view");

        this._parentContainer = null;
        this._isClosed = false;
        this._visible = false;
    }

    // Static

    static shouldNotRemoveFromDOMWhenHidden()
    {
        // Implemented by subclasses.
        // Returns true if the content view should *not* be detached from the DOM when hidden.
        return false;
    }

    static createFromRepresentedObject(representedObject, extraArguments)
    {
        console.assert(representedObject);

        if (representedObject instanceof WI.Frame)
            return new WI.ResourceClusterContentView(representedObject.mainResource, extraArguments);

        if (representedObject instanceof WI.Resource)
            return new WI.ResourceClusterContentView(representedObject, extraArguments);

        if (representedObject instanceof WI.Script)
            return new WI.ScriptContentView(representedObject, extraArguments);

        if (representedObject instanceof WI.CSSStyleSheet)
            return new WI.TextResourceContentView(representedObject, extraArguments);

        if (representedObject instanceof WI.Canvas)
            return new WI.CanvasContentView(representedObject, extraArguments);

        if (representedObject instanceof WI.ShaderProgram)
            return new WI.ShaderProgramContentView(representedObject, extraArguments);

        if (representedObject instanceof WI.TimelineRecording)
            return new WI.TimelineRecordingContentView(representedObject, extraArguments);

        if (representedObject instanceof WI.Timeline) {
            var timelineType = representedObject.type;
            if (timelineType === WI.TimelineRecord.Type.Network)
                return new WI.NetworkTimelineView(representedObject, extraArguments);

            if (timelineType === WI.TimelineRecord.Type.Layout)
                return new WI.LayoutTimelineView(representedObject, extraArguments);

            if (timelineType === WI.TimelineRecord.Type.Script)
                return new WI.ScriptClusterTimelineView(representedObject, extraArguments);

            if (timelineType === WI.TimelineRecord.Type.RenderingFrame)
                return new WI.RenderingFrameTimelineView(representedObject, extraArguments);

            if (timelineType === WI.TimelineRecord.Type.CPU)
                return new WI.CPUTimelineView(representedObject, extraArguments);

            if (timelineType === WI.TimelineRecord.Type.Memory)
                return new WI.MemoryTimelineView(representedObject, extraArguments);

            if (timelineType === WI.TimelineRecord.Type.HeapAllocations)
                return new WI.HeapAllocationsTimelineView(representedObject, extraArguments);

            if (timelineType === WI.TimelineRecord.Type.Media)
                return new WI.MediaTimelineView(representedObject, extraArguments);
        }

        if (representedObject instanceof WI.JavaScriptBreakpoint || representedObject instanceof WI.IssueMessage) {
            if (representedObject.sourceCodeLocation)
                return WI.ContentView.createFromRepresentedObject(representedObject.sourceCodeLocation.displaySourceCode, extraArguments);
        }

        if (representedObject instanceof WI.LocalResourceOverride) {
            if (representedObject.type === WI.LocalResourceOverride.InterceptType.Request)
                return new WI.LocalResourceOverrideRequestContentView(representedObject);
            return WI.ContentView.createFromRepresentedObject(representedObject.localResource);
        }

        if (representedObject instanceof WI.DOMStorageObject)
            return new WI.DOMStorageContentView(representedObject, extraArguments);

        if (representedObject instanceof WI.CookieStorageObject)
            return new WI.CookieStorageContentView(representedObject, extraArguments);

        if (representedObject instanceof WI.DatabaseTableObject)
            return new WI.DatabaseTableContentView(representedObject, extraArguments);

        if (representedObject instanceof WI.DatabaseObject)
            return new WI.DatabaseContentView(representedObject, extraArguments);

        if (representedObject instanceof WI.IndexedDatabase)
            return new WI.IndexedDatabaseContentView(representedObject, extraArguments);

        if (representedObject instanceof WI.IndexedDatabaseObjectStore)
            return new WI.IndexedDatabaseObjectStoreContentView(representedObject, extraArguments);

        if (representedObject instanceof WI.IndexedDatabaseObjectStoreIndex)
            return new WI.IndexedDatabaseObjectStoreContentView(representedObject, extraArguments);

        if (representedObject instanceof WI.ApplicationCacheFrame)
            return new WI.ApplicationCacheFrameContentView(representedObject, extraArguments);

        if (representedObject instanceof WI.DOMTree)
            return new WI.FrameDOMTreeContentView(representedObject, extraArguments);

        if (representedObject instanceof WI.DOMSearchMatchObject) {
            var resultView = new WI.FrameDOMTreeContentView(WI.networkManager.mainFrame.domTree, extraArguments);
            resultView.restoreFromCookie({nodeToSelect: representedObject.domNode});
            return resultView;
        }

        if (representedObject instanceof WI.DOMNode) {
            if (representedObject.frame) {
                let resultView = WI.ContentView.createFromRepresentedObject(representedObject.frame, extraArguments);
                resultView.restoreFromCookie({nodeToSelect: representedObject});
                return resultView;
            }
        }

        if (representedObject instanceof WI.SourceCodeSearchMatchObject) {
            var resultView;
            if (representedObject.sourceCode instanceof WI.Resource)
                resultView = new WI.ResourceClusterContentView(representedObject.sourceCode, extraArguments);
            else if (representedObject.sourceCode instanceof WI.Script)
                resultView = new WI.ScriptContentView(representedObject.sourceCode, extraArguments);
            else
                console.error("Unknown SourceCode", representedObject.sourceCode);

            var textRangeToSelect = representedObject.sourceCodeTextRange.formattedTextRange;
            var startPosition = textRangeToSelect.startPosition();
            resultView.restoreFromCookie({lineNumber: startPosition.lineNumber, columnNumber: startPosition.columnNumber});

            return resultView;
        }

        if (representedObject instanceof WI.LogObject)
            return new WI.LogContentView(representedObject, extraArguments);

        if (representedObject instanceof WI.CallingContextTree)
            return new WI.ProfileView(representedObject, extraArguments);

        if (representedObject instanceof WI.HeapSnapshotProxy || representedObject instanceof WI.HeapSnapshotDiffProxy)
            return new WI.HeapSnapshotClusterContentView(representedObject, extraArguments);

        if (representedObject instanceof WI.Recording)
            return new WI.RecordingContentView(representedObject, extraArguments);

        if (representedObject instanceof WI.ResourceCollection)
            return new WI.ResourceCollectionContentView(representedObject, extraArguments);

        if (representedObject instanceof WI.AuditTestCase || representedObject instanceof WI.AuditTestCaseResult)
            return new WI.AuditTestCaseContentView(representedObject, extraArguments);

        if (representedObject instanceof WI.AuditTestGroup || representedObject instanceof WI.AuditTestGroupResult)
            return new WI.AuditTestGroupContentView(representedObject, extraArguments);

        if (representedObject instanceof WI.Animation)
            return new WI.AnimationContentView(representedObject, extraArguments);

        if (representedObject instanceof WI.Collection)
            return new WI.CollectionContentView(representedObject, extraArguments);

        if (typeof representedObject === "string" || representedObject instanceof String)
            return new WI.TextContentView(representedObject, extraArguments);

        console.assert(!WI.ContentView.isViewable(representedObject));

        throw new Error("Can't make a ContentView for an unknown representedObject of type: " + representedObject.constructor.name);
    }

    static contentViewForRepresentedObject(representedObject, onlyExisting, extraArguments)
    {
        console.assert(representedObject);

        // Some represented objects attempt to resolve a better represented object.
        // This may result in null, for example a Breakpoint which doesn't have a SourceCode.
        let resolvedRepresentedObject = WI.ContentView.resolvedRepresentedObjectForRepresentedObject(representedObject);
        if (!resolvedRepresentedObject)
            return null;

        let existingContentView = resolvedRepresentedObject[WI.ContentView.ContentViewForRepresentedObjectSymbol];
        console.assert(!existingContentView || existingContentView instanceof WI.ContentView);
        if (existingContentView)
            return existingContentView;

        if (onlyExisting)
            return null;

        let newContentView = WI.ContentView.createFromRepresentedObject(representedObject, extraArguments);
        console.assert(newContentView instanceof WI.ContentView);
        if (!newContentView)
            return null;

        console.assert(newContentView.representedObject === resolvedRepresentedObject, "createFromRepresentedObject and resolvedRepresentedObjectForRepresentedObject are out of sync for type", representedObject.constructor.name);
        if (typeof resolvedRepresentedObject === "object")
            newContentView.representedObject[WI.ContentView.ContentViewForRepresentedObjectSymbol] = newContentView;
        return newContentView;
    }

    static closedContentViewForRepresentedObject(representedObject)
    {
        let resolvedRepresentedObject = WI.ContentView.resolvedRepresentedObjectForRepresentedObject(representedObject);
        if (typeof resolvedRepresentedObject === "object")
            resolvedRepresentedObject[WI.ContentView.ContentViewForRepresentedObjectSymbol] = null;
    }

    static resolvedRepresentedObjectForRepresentedObject(representedObject)
    {
        if (representedObject instanceof WI.Frame)
            return representedObject.mainResource;

        if (representedObject instanceof WI.JavaScriptBreakpoint || representedObject instanceof WI.IssueMessage) {
            if (representedObject.sourceCodeLocation)
                return representedObject.sourceCodeLocation.displaySourceCode;
            return representedObject;
        }

        if (representedObject instanceof WI.DOMBreakpoint) {
            if (representedObject.domNode)
                return WI.ContentView.resolvedRepresentedObjectForRepresentedObject(representedObject.domNode);
            return representedObject;
        }

        if (representedObject instanceof WI.DOMNode) {
            if (representedObject.frame)
                return WI.ContentView.resolvedRepresentedObjectForRepresentedObject(representedObject.frame);
            return representedObject;
        }

        if (representedObject instanceof WI.DOMSearchMatchObject)
            return WI.networkManager.mainFrame.domTree;

        if (representedObject instanceof WI.SourceCodeSearchMatchObject)
            return representedObject.sourceCode;

        if (representedObject instanceof WI.LocalResourceOverride) {
            if (representedObject.type !== WI.LocalResourceOverride.InterceptType.Request)
                return representedObject.localResource;
            return representedObject;
        }

        return representedObject;
    }

    static isViewable(representedObject)
    {
        if (representedObject instanceof WI.Frame)
            return true;
        if (representedObject instanceof WI.Resource)
            return true;
        if (representedObject instanceof WI.Script)
            return true;
        if (representedObject instanceof WI.CSSStyleSheet)
            return true;
        if (representedObject instanceof WI.Canvas)
            return true;
        if (representedObject instanceof WI.ShaderProgram)
            return true;
        if (representedObject instanceof WI.TimelineRecording)
            return true;
        if (representedObject instanceof WI.Timeline)
            return true;
        if (representedObject instanceof WI.JavaScriptBreakpoint || representedObject instanceof WI.IssueMessage)
            return representedObject.sourceCodeLocation;
        if (representedObject instanceof WI.LocalResourceOverride)
            return true;
        if (representedObject instanceof WI.DOMStorageObject)
            return true;
        if (representedObject instanceof WI.CookieStorageObject)
            return true;
        if (representedObject instanceof WI.DatabaseTableObject)
            return true;
        if (representedObject instanceof WI.DatabaseObject)
            return true;
        if (representedObject instanceof WI.IndexedDatabase)
            return true;
        if (representedObject instanceof WI.IndexedDatabaseObjectStore)
            return true;
        if (representedObject instanceof WI.IndexedDatabaseObjectStoreIndex)
            return true;
        if (representedObject instanceof WI.ApplicationCacheFrame)
            return true;
        if (representedObject instanceof WI.DOMTree)
            return true;
        if (representedObject instanceof WI.DOMSearchMatchObject)
            return true;
        if (representedObject instanceof WI.SourceCodeSearchMatchObject)
            return true;
        if (representedObject instanceof WI.LogObject)
            return true;
        if (representedObject instanceof WI.CallingContextTree)
            return true;
        if (representedObject instanceof WI.HeapSnapshotProxy || representedObject instanceof WI.HeapSnapshotDiffProxy)
            return true;
        if (representedObject instanceof WI.Recording)
            return true;
        if (representedObject instanceof WI.AuditTestCase || representedObject instanceof WI.AuditTestGroup
            || representedObject instanceof WI.AuditTestCaseResult || representedObject instanceof WI.AuditTestGroupResult)
            return true;
        if (representedObject instanceof WI.Animation)
            return true;
        if (representedObject instanceof WI.Collection)
            return true;
        if (typeof representedObject === "string" || representedObject instanceof String)
            return true;
        if (representedObject[WI.ContentView.isViewableSymbol])
            return true;
        return false;
    }

    // Public

    get isClosed() { return this._isClosed; }

    get visible()
    {
        return !this.isClosed && this._visible;
    }

    set visible(value)
    {
        this._visible = !!value;
        this.element.classList.toggle("not-visible", !this._visible);
    }

    get representedObject()
    {
        return this._representedObject;
    }

    get navigationItems()
    {
        // Navigation items that will be displayed by the ContentBrowser instance,
        // meant to be subclassed. Implemented by subclasses.
        return [];
    }

    get parentContainer()
    {
        return this._parentContainer;
    }

    get scrollableElements()
    {
        // Implemented by subclasses.
        return [];
    }

    get shouldKeepElementsScrolledToBottom()
    {
        // Implemented by subclasses.
        return false;
    }

    get shouldSaveStateWhenHidden()
    {
        return false;
    }

    get selectionPathComponents()
    {
        // Implemented by subclasses.
        return [];
    }

    get supplementalRepresentedObjects()
    {
        // Implemented by subclasses.
        return [];
    }

    get supportsSplitContentBrowser()
    {
        // Implemented by subclasses.
        return WI.dockedConfigurationSupportsSplitContentBrowser();
    }

    closed()
    {
        // Implemented by subclasses.
        this._isClosed = true;
    }

    saveToCookie(cookie)
    {
        // Implemented by subclasses.
    }

    restoreFromCookie(cookie)
    {
        // Implemented by subclasses.
    }

    canGoBack()
    {
        // Implemented by subclasses.
        return false;
    }

    canGoForward()
    {
        // Implemented by subclasses.
        return false;
    }

    goBack()
    {
        // Implemented by subclasses.
    }

    goForward()
    {
        // Implemented by subclasses.
    }

    get supportsSearch()
    {
        // Implemented by subclasses.
        return false;
    }

    get supportsCustomFindBanner()
    {
        // Implemented by subclasses.
        return false;
    }

    showCustomFindBanner()
    {
        // Implemented by subclasses.
    }

    get numberOfSearchResults()
    {
        // Implemented by subclasses.
        return null;
    }

    get hasPerformedSearch()
    {
        // Implemented by subclasses.
        return false;
    }

    set automaticallyRevealFirstSearchResult(reveal)
    {
        // Implemented by subclasses.
    }

    performSearch(query)
    {
        // Implemented by subclasses.
    }

    searchHidden()
    {
        // Implemented by subclasses.
    }

    searchCleared()
    {
        // Implemented by subclasses.
    }

    searchQueryWithSelection()
    {
        let selection = window.getSelection();
        if (selection.isCollapsed)
            return null;

        return selection.toString().removeWordBreakCharacters();
    }

    revealPreviousSearchResult(changeFocus)
    {
        // Implemented by subclasses.
    }

    revealNextSearchResult(changeFocus)
    {
        // Implemented by subclasses.
    }
};

WI.ContentView.Event = {
    SelectionPathComponentsDidChange: "content-view-selection-path-components-did-change",
    SupplementalRepresentedObjectsDidChange: "content-view-supplemental-represented-objects-did-change",
    NumberOfSearchResultsDidChange: "content-view-number-of-search-results-did-change",
    NavigationItemsDidChange: "content-view-navigation-items-did-change"
};

WI.ContentView.isViewableSymbol = Symbol("is-viewable");
WI.ContentView.ContentViewForRepresentedObjectSymbol = Symbol("content-view-for-represented-object");
