/*
 * Copyright (C) 2013, 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.ResourceClusterContentView = class ResourceClusterContentView extends WI.ClusterContentView
{
    constructor(resource)
    {
        super(resource);

        this._resource = resource;
        this._resource.addEventListener(WI.Resource.Event.TypeDidChange, this._resourceTypeDidChange, this);
        this._resource.addEventListener(WI.Resource.Event.LoadingDidFinish, this._resourceLoadingDidFinish, this);

        this._responsePathComponent = this._createPathComponent({
            displayName: WI.UIString("Response"),
            identifier: ResourceClusterContentView.Identifier.Response,
            styleClassNames: ["response-icon"],
        });

        if (this._canShowRequestContentView()) {
            this._requestPathComponent = this._createPathComponent({
                displayName: WI.UIString("Request"),
                identifier: ResourceClusterContentView.Identifier.Request,
                styleClassNames: ["request-icon"],
                nextSibling: this._responsePathComponent,
            });

            this._tryEnableCustomRequestContentViews();
        }

        // FIXME: Since a custom response content view may only become available after a response is received
        // we need to figure out a way to restore / prefer the custom content view. For example if users
        // always want to prefer the JSON view to the normal Response text view.

        this._currentContentViewSetting = new WI.Setting("resource-current-view-" + this._resource.url.hash, ResourceClusterContentView.Identifier.Response);

        this._tryEnableCustomResponseContentViews();
    }

    // Public

    get resource() { return this._resource; }

    get selectionPathComponents()
    {
        let currentContentView = this._contentViewContainer.currentContentView;
        if (!currentContentView)
            return [];

        if (!this._canShowRequestContentView() && !this._canShowCustomRequestContentView() && !this._canShowCustomResponseContentView())
            return currentContentView.selectionPathComponents;

        // Append the current view's path components to the path component representing the current view.
        let components = [this._pathComponentForContentView(currentContentView)];
        return components.concat(currentContentView.selectionPathComponents);
    }

    shown()
    {
        super.shown();

        if (this._shownInitialContent)
            return;

        this._showContentViewForIdentifier(this._currentContentViewSetting.value);
    }

    closed()
    {
        super.closed();

        this._shownInitialContent = false;
    }

    restoreFromCookie(cookie)
    {
        let contentView = this._showContentViewForIdentifier(cookie[WI.ResourceClusterContentView.ContentViewIdentifierCookieKey]);
        if (typeof contentView.revealPosition === "function" && "lineNumber" in cookie && "columnNumber" in cookie)
            contentView.revealPosition(new WI.SourceCodePosition(cookie.lineNumber, cookie.columnNumber));
    }

    showRequest()
    {
        this._shownInitialContent = true;

        return this._showContentViewForIdentifier(ResourceClusterContentView.Identifier.Request);
    }

    showResponse(positionToReveal, textRangeToSelect, forceUnformatted)
    {
        this._shownInitialContent = true;

        if (!this._resource.finished) {
            this._positionToReveal = positionToReveal;
            this._textRangeToSelect = textRangeToSelect;
            this._forceUnformatted = forceUnformatted;
        }

        let responseContentView = this._showContentViewForIdentifier(ResourceClusterContentView.Identifier.Response);
        if (typeof responseContentView.revealPosition === "function")
            responseContentView.revealPosition(positionToReveal, textRangeToSelect, forceUnformatted);
        return responseContentView;
    }

    // Private

    get requestContentView()
    {
        if (!this._canShowRequestContentView())
            return null;

        if (this._requestContentView)
            return this._requestContentView;

        this._requestContentView = new WI.TextContentView(this._resource.requestData || "", this._resource.requestDataContentType);

        return this._requestContentView;
    }

    get responseContentView()
    {
        if (this._responseContentView)
            return this._responseContentView;

        this._responseContentView = this._contentViewForResourceType(this._resource.type);
        if (this._responseContentView)
            return this._responseContentView;

        let typeFromMIMEType = WI.Resource.typeFromMIMEType(this._resource.mimeType);
        this._responseContentView = this._contentViewForResourceType(typeFromMIMEType);
        if (this._responseContentView)
            return this._responseContentView;

        if (WI.shouldTreatMIMETypeAsText(this._resource.mimeType)) {
            this._responseContentView = new WI.TextResourceContentView(this._resource);
            return this._responseContentView;
        }

        this._responseContentView = new WI.GenericResourceContentView(this._resource);
        return this._responseContentView;
    }

    get customRequestDOMContentView()
    {
        if (!this._customRequestDOMContentView && this._customRequestDOMContentViewInitializer)
            this._customRequestDOMContentView = this._customRequestDOMContentViewInitializer();
        return this._customRequestDOMContentView;
    }

    get customRequestJSONContentView()
    {
        if (!this._customRequestJSONContentView && this._customRequestJSONContentViewInitializer)
            this._customRequestJSONContentView = this._customRequestJSONContentViewInitializer();
        return this._customRequestJSONContentView;
    }

    get customResponseDOMContentView()
    {
        if (!this._customResponseDOMContentView && this._customResponseDOMContentViewInitializer)
            this._customResponseDOMContentView = this._customResponseDOMContentViewInitializer();
        return this._customResponseDOMContentView;
    }

    get customResponseJSONContentView()
    {
        if (!this._customResponseJSONContentView && this._customResponseJSONContentViewInitializer)
            this._customResponseJSONContentView = this._customResponseJSONContentViewInitializer();
        return this._customResponseJSONContentView;
    }

    get customResponseTextContentView()
    {
        if (!this._customResponseTextContentView && this._customResponseTextContentViewInitializer)
            this._customResponseTextContentView = this._customResponseTextContentViewInitializer();
        return this._customResponseTextContentView;
    }

    _createPathComponent({displayName, styleClassNames, identifier, previousSibling, nextSibling})
    {
        const textOnly = false;
        const showSelectorArrows = true;
        let pathComponent = new WI.HierarchicalPathComponent(displayName, styleClassNames, identifier, textOnly, showSelectorArrows);
        pathComponent.comparisonData = this._resource;

        if (previousSibling) {
            previousSibling.nextSibling = pathComponent;
            pathComponent.previousSibling = previousSibling;
        }

        if (nextSibling) {
            nextSibling.previousSibling = pathComponent;
            pathComponent.nextSibling = nextSibling;
        }

        pathComponent.addEventListener(WI.HierarchicalPathComponent.Event.SiblingWasSelected, this._pathComponentSelected, this);

        return pathComponent;
    }

    _canShowRequestContentView()
    {
        let requestData = this._resource.requestData;
        if (!requestData)
            return false;

        if (this._resource.hasRequestFormParameters())
            return false;

        return true;
    }

    _canShowCustomRequestContentView()
    {
        return !!(this._customRequestDOMContentViewInitializer || this._customRequestJSONContentViewInitializer);
    }

    _canShowCustomResponseContentView()
    {
        return !!(this._customResponseDOMContentViewInitializer || this._customResponseJSONContentViewInitializer || this._customResponseTextContentViewInitializer);
    }

    _contentViewForResourceType(type)
    {
        switch (type) {
        case WI.Resource.Type.Document:
        case WI.Resource.Type.Script:
        case WI.Resource.Type.StyleSheet:
            return new WI.TextResourceContentView(this._resource);

        case WI.Resource.Type.Image:
            return new WI.ImageResourceContentView(this._resource);

        case WI.Resource.Type.Font:
            return new WI.FontResourceContentView(this._resource);

        case WI.Resource.Type.WebSocket:
            return new WI.WebSocketContentView(this._resource);

        default:
            return null;
        }
    }

    _pathComponentForContentView(contentView)
    {
        switch (contentView) {
        case this._requestContentView:
            return this._requestPathComponent;

        case this._customRequestDOMContentView:
            return this._customRequestDOMPathComponent;

        case this._customRequestJSONContentView:
            return this._customRequestJSONPathComponent;

        case this._responseContentView:
            return this._responsePathComponent;

        case this._customResponseDOMContentView:
            return this._customResponseDOMPathComponent;

        case this._customResponseJSONContentView:
            return this._customResponseJSONPathComponent;

        case this._customResponseTextContentView:
            return this._customResponseTextPathComponent;
        }

        console.error("Unknown contentView", contentView);
        return null;
    }

    _identifierForContentView(contentView)
    {
        console.assert(contentView);

        switch (contentView) {
        case this._requestContentView:
            return ResourceClusterContentView.Identifier.Request;

        case this._customRequestDOMContentView:
            return ResourceClusterContentView.Identifier.RequestDOM;

        case this._customRequestJSONContentView:
            return ResourceClusterContentView.Identifier.RequestJSON;

        case this._responseContentView:
            return ResourceClusterContentView.Identifier.Response;

        case this._customResponseDOMContentView:
            return ResourceClusterContentView.Identifier.ResponseDOM;

        case this._customResponseJSONContentView:
            return ResourceClusterContentView.Identifier.ResponseJSON;

        case this._customResponseTextContentView:
            return ResourceClusterContentView.Identifier.ResponseText;
        }

        console.error("Unknown contentView", contentView);
        return null;
    }

    _showContentViewForIdentifier(identifier)
    {
        let contentViewToShow = null;

        // This is expected to fall through all the way to the `default`.
        switch (identifier) {
        case ResourceClusterContentView.Identifier.RequestDOM:
            contentViewToShow = this.customRequestDOMContentView;
            if (contentViewToShow)
                break;
            // fallthrough
        case ResourceClusterContentView.Identifier.RequestJSON:
            contentViewToShow = this.customRequestJSONContentView;
            if (contentViewToShow)
                break;
            // fallthrough
        case ResourceClusterContentView.Identifier.Request:
            contentViewToShow = this.requestContentView;
            if (contentViewToShow)
                break;
            // fallthrough
        case ResourceClusterContentView.Identifier.ResponseDOM:
            contentViewToShow = this.customResponseDOMContentView;
            if (contentViewToShow)
                break;
            // fallthrough
        case ResourceClusterContentView.Identifier.ResponseJSON:
            contentViewToShow = this.customResponseJSONContentView;
            if (contentViewToShow)
                break;
            // fallthrough
        case ResourceClusterContentView.Identifier.ResponseText:
            contentViewToShow = this.customResponseTextContentView;
            if (contentViewToShow)
                break;
            // fallthrough
        case ResourceClusterContentView.Identifier.Response:
        default:
            contentViewToShow = this.responseContentView;
            break;
        }

        console.assert(contentViewToShow);

        this._currentContentViewSetting.value = this._identifierForContentView(contentViewToShow);

        return this.contentViewContainer.showContentView(contentViewToShow);
    }

    _pathComponentSelected(event)
    {
        this._showContentViewForIdentifier(event.data.pathComponent.representedObject);
    }

    _resourceTypeDidChange(event)
    {
        // Since resource views are based on the type, we need to make a new content view and tell the container to replace this
        // content view with the new one. Make a new ResourceContentView which will use the new resource type to make the correct
        // concrete ResourceContentView subclass.

        let currentResponseContentView = this._responseContentView;
        if (!currentResponseContentView)
            return;

        this._responseContentView = null;

        this.contentViewContainer.replaceContentView(currentResponseContentView, this.responseContentView);
    }

    _resourceLoadingDidFinish(event)
    {
        this._tryEnableCustomResponseContentViews();

        if ("_positionToReveal" in this) {
            if (this._contentViewContainer.currentContentView === this._responseContentView)
                this._responseContentView.revealPosition(this._positionToReveal, this._textRangeToSelect, this._forceUnformatted);

            delete this._positionToReveal;
            delete this._textRangeToSelect;
            delete this._forceUnformatted;
        }
    }

    _canUseJSONContentViewForContent(content)
    {
        return typeof content === "string" && content.isJSON((json) => json && (typeof json === "object" || Array.isArray(json)));
    }

    _canUseDOMContentViewForContent(content, mimeType)
    {
        if (typeof content !== "string")
            return false;

        switch (mimeType) {
        case "text/html":
            return true;

        case "text/xml":
        case "application/xml":
        case "application/xhtml+xml":
        case "image/svg+xml":
            try {
                let dom = (new DOMParser).parseFromString(content, mimeType);
                return !dom.querySelector("parsererror");
            } catch { }
            return false;
        }

        return false;
    }

    _normalizeMIMETypeForDOM(mimeType)
    {
        mimeType = parseMIMEType(mimeType).type;

        if (mimeType.endsWith("/html") || mimeType.endsWith("+html"))
            return "text/html";

        if (mimeType.endsWith("/xml") || mimeType.endsWith("+xml")) {
            if (mimeType !== "application/xhtml+xml" && mimeType !== "image/svg+xml")
                return "application/xml";
        }

        if (mimeType.endsWith("/xhtml") || mimeType.endsWith("+xhtml"))
            return "application/xhtml+xml";

        if (mimeType.endsWith("/svg") || mimeType.endsWith("+svg"))
            return "image/svg+xml";

        return mimeType;
    }

    _tryEnableCustomRequestContentViews()
    {
        let content = this._resource.requestData;

        if (this._canUseJSONContentViewForContent(content)) {
            this._customRequestJSONContentViewInitializer = () => new WI.LocalJSONContentView(content, this._resource);

            this._customRequestJSONPathComponent = this._createPathComponent({
                displayName: WI.UIString("Request (Object Tree)"),
                styleClassNames: ["object-icon"],
                identifier: ResourceClusterContentView.Identifier.RequestJSON,
                previousSibling: this._requestPathComponent,
                nextSibling: this._responsePathComponent,
            });

            this.dispatchEventToListeners(WI.ContentView.Event.SelectionPathComponentsDidChange);
            return;
        }

        let mimeType = this._normalizeMIMETypeForDOM(this._resource.requestDataContentType);

        if (this._canUseDOMContentViewForContent(content, mimeType)) {
            this._customRequestDOMContentViewInitializer = () => new WI.LocalDOMContentView(content, mimeType, this._resource);

            this._customRequestDOMPathComponent = this._createPathComponent({
                displayName: WI.UIString("Request (DOM Tree)"),
                styleClassNames: ["dom-document-icon"],
                identifier: ResourceClusterContentView.Identifier.RequestDOM,
                previousSibling: this._requestPathComponent,
                nextSibling: this._responsePathComponent,
            });

            this.dispatchEventToListeners(WI.ContentView.Event.SelectionPathComponentsDidChange);
            return;
        }
    }

    _tryEnableCustomResponseContentViews()
    {
        if (!this._resource.hasResponse())
            return;

        // WebSocket resources already use a "custom" response content view.
        if (this._resource instanceof WI.WebSocketResource)
            return;

        this._resource.requestContent()
        .then(({error, content}) => {
            if (error || typeof content !== "string")
                return;

            if (this._canUseJSONContentViewForContent(content)) {
                this._customResponseJSONContentViewInitializer = () => new WI.LocalJSONContentView(content, this._resource);

                this._customResponseJSONPathComponent = this._createPathComponent({
                    displayName: WI.UIString("Response (Object Tree)"),
                    styleClassNames: ["object-icon"],
                    identifier: ResourceClusterContentView.Identifier.ResponseJSON,
                    previousSibling: this._responsePathComponent,
                });

                this.dispatchEventToListeners(WI.ContentView.Event.SelectionPathComponentsDidChange);
                return;
            }

            let mimeType = this._normalizeMIMETypeForDOM(this._resource.mimeType);

            if (this._canUseDOMContentViewForContent(content, mimeType)) {
                if (mimeType === "image/svg+xml") {
                    this._customResponseTextContentViewInitializer = () => new WI.TextContentView(content, mimeType, this._resource);

                    this._customResponseTextPathComponent = this._createPathComponent({
                        displayName: WI.UIString("Response (Text)"),
                        styleClassNames: ["source-icon"],
                        identifier: ResourceClusterContentView.Identifier.ResponseText,
                        previousSibling: this._responsePathComponent,
                    });
                }

                this._customResponseDOMContentViewInitializer = () => new WI.LocalDOMContentView(content, mimeType, this._resource);

                this._customResponseDOMPathComponent = this._createPathComponent({
                    displayName: WI.UIString("Response (DOM Tree)"),
                    styleClassNames: ["dom-document-icon"],
                    identifier: ResourceClusterContentView.Identifier.ResponseDOM,
                    previousSibling: this._customResponseTextPathComponent || this._responsePathComponent,
                });

                this.dispatchEventToListeners(WI.ContentView.Event.SelectionPathComponentsDidChange);
                return;
            }
        });
    }
};

WI.ResourceClusterContentView.ContentViewIdentifierCookieKey = "resource-cluster-content-view-identifier";

WI.ResourceClusterContentView.Identifier = {
    Request: "request",
    RequestDOM: "request-dom",
    RequestJSON: "request-json",
    Response: "response",
    ResponseDOM: "response-dom",
    ResponseJSON: "response-json",
    ResponseText: "response-text",
};
