/*
 * Copyright (C) 2013-2019 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.ResourceContentView = class ResourceContentView extends WI.ContentView
{
    constructor(resource, styleClassName)
    {
        console.assert(resource instanceof WI.Resource || resource instanceof WI.CSSStyleSheet, resource);
        console.assert(typeof styleClassName === "string");

        super(resource);

        this._resource = resource;

        this.element.classList.add(styleClassName, "resource");

        this._spinnerTimeout = setTimeout(() => {
            // Append a spinner while waiting for contentAvailable. Subclasses are responsible for
            // removing the spinner before showing the resource content by calling removeLoadingIndicator.
            let spinner = new WI.IndeterminateProgressSpinner;
            this.element.appendChild(spinner.element);

            this._spinnerTimeout = undefined;
        }, 100);

        this.element.addEventListener("click", this._mouseWasClicked.bind(this), false);

        // Request content last so the spinner will always be removed in case the content is immediately available.
        resource.requestContent().then(this._contentAvailable.bind(this)).catch(this.showGenericErrorMessage.bind(this));

        if (!this.managesOwnIssues) {
            WI.consoleManager.addEventListener(WI.ConsoleManager.Event.IssueAdded, this._issueWasAdded, this);

            var issues = WI.consoleManager.issuesForSourceCode(resource);
            for (var i = 0; i < issues.length; ++i)
                this.addIssue(issues[i]);
        }

        this._showingLocalResourceOverride = false;

        if (WI.NetworkManager.supportsLocalResourceOverrides()) {
            if (resource.isLocalResourceOverride) {
                this._showingLocalResourceOverride = true;

                this._localResourceOverrideBannerView = new WI.LocalResourceOverrideLabelView(resource);

                this._removeLocalResourceOverrideButtonNavigationItem = new WI.ButtonNavigationItem("remove-local-resource-override", WI.UIString("Remove Local Override"), "Images/NavigationItemTrash.svg", 15, 15);
                this._removeLocalResourceOverrideButtonNavigationItem.addEventListener(WI.ButtonNavigationItem.Event.Clicked, this._handleRemoveLocalResourceOverride, this);
                this._removeLocalResourceOverrideButtonNavigationItem.enabled = true;
                this._removeLocalResourceOverrideButtonNavigationItem.visibilityPriority = WI.NavigationItem.VisibilityPriority.Low;
            } else {
                this._localResourceOverrideBannerView = new WI.LocalResourceOverrideWarningView(resource);

                this._createLocalResourceOverrideButtonNavigationItem = new WI.ButtonNavigationItem("create-local-resource-override", WI.UIString("Create Local Override"), "Images/NavigationItemNetworkOverride.svg", 13, 14);
                this._createLocalResourceOverrideButtonNavigationItem.addEventListener(WI.ButtonNavigationItem.Event.Clicked, this._handleCreateLocalResourceOverride, this);
                this._createLocalResourceOverrideButtonNavigationItem.enabled = false; // Enabled when the content is available.
                this._createLocalResourceOverrideButtonNavigationItem.visibilityPriority = WI.NavigationItem.VisibilityPriority.Low;
            }

            WI.networkManager.addEventListener(WI.NetworkManager.Event.LocalResourceOverrideAdded, this._handleLocalResourceOverrideChanged, this);
            WI.networkManager.addEventListener(WI.NetworkManager.Event.LocalResourceOverrideRemoved, this._handleLocalResourceOverrideChanged, this);
        }
    }

    // Public

    get resource() { return this._resource; }
    get showingLocalResourceOverride() { return this._showingLocalResourceOverride; }

    get navigationItems()
    {
        let items = [];

        if (this._removeLocalResourceOverrideButtonNavigationItem)
            items.push(this._removeLocalResourceOverrideButtonNavigationItem);
        if (this._createLocalResourceOverrideButtonNavigationItem)
            items.push(this._createLocalResourceOverrideButtonNavigationItem);

        return items;
    }

    get supportsSave()
    {
        return this._resource.finished;
    }

    get saveData()
    {
        return {url: this._resource.url, content: this._resource.content};
    }

    contentAvailable(content, base64Encoded)
    {
        throw WI.NotImplementedError.subclassMustOverride();
    }

    localResourceOverrideInitialContent()
    {
        // Implemented by subclasses if needed.
        return {};
    }

    showGenericNoContentMessage()
    {
        this.showMessage(WI.UIString("Resource has no content"));

        this.dispatchEventToListeners(WI.ResourceContentView.Event.ContentError);
    }

    showGenericErrorMessage()
    {
        this._contentError(WI.UIString("An error occurred trying to load the resource."));
    }

    showMessage(message)
    {
        this.element.removeChildren();
        this.element.appendChild(WI.createMessageTextView(message));
    }

    addIssue(issue)
    {
        // This generically shows only the last issue, subclasses can override for better handling.
        this.element.removeChildren();
        this.element.appendChild(WI.createMessageTextView(issue.text, issue.level === WI.IssueMessage.Level.Error));
    }

    closed()
    {
        super.closed();

        if (WI.NetworkManager.supportsLocalResourceOverrides())
            WI.networkManager.removeEventListener(null, null, this);

        if (!this.managesOwnIssues)
            WI.consoleManager.removeEventListener(null, null, this);
    }

    // Protected

    removeLoadingIndicator()
    {
        if (this._spinnerTimeout) {
            clearTimeout(this._spinnerTimeout);
            this._spinnerTimeout = undefined;
        }

        this.removeAllSubviews();

        if (this._localResourceOverrideBannerView)
            this.addSubview(this._localResourceOverrideBannerView);
    }

    // Private

    _contentAvailable(parameters)
    {
        if (parameters.error) {
            this._contentError(parameters.error);
            return;
        }

        if (parameters.message) {
            this.showMessage(parameters.message);
            return;
        }

        // Content is ready to show, call the public method now.
        console.assert(!this._hasContent());
        console.assert(parameters.sourceCode === this._resource);
        this.contentAvailable(parameters.sourceCode.content, parameters.base64Encoded);

        if (this._createLocalResourceOverrideButtonNavigationItem)
            this._createLocalResourceOverrideButtonNavigationItem.enabled = WI.networkManager.canBeOverridden(this._resource);
    }

    _contentError(error)
    {
        if (this._hasContent())
            return;

        this.removeLoadingIndicator();

        this.element.appendChild(WI.createMessageTextView(error, true));

        this.dispatchEventToListeners(WI.ResourceContentView.Event.ContentError);
    }

    _hasContent()
    {
        return this.element.hasChildNodes() && !this.element.querySelector(".indeterminate-progress-spinner");
    }

    _issueWasAdded(event)
    {
        console.assert(!this.managesOwnIssues);

        var issue = event.data.issue;
        if (!WI.ConsoleManager.issueMatchSourceCode(issue, this._resource))
            return;

        this.addIssue(issue);
    }

    async _handleCreateLocalResourceOverride(event)
    {
        let initialContent = this.localResourceOverrideInitialContent();
        let localResourceOverride = await this._resource.createLocalResourceOverride(initialContent);
        WI.networkManager.addLocalResourceOverride(localResourceOverride);
        WI.showLocalResourceOverride(localResourceOverride);
    }

    _handleRemoveLocalResourceOverride(event)
    {
        console.assert(this._showingLocalResourceOverride);

        let localResourceOverride = WI.networkManager.localResourceOverrideForURL(this._resource.url);
        WI.networkManager.removeLocalResourceOverride(localResourceOverride);
    }

    _handleLocalResourceOverrideChanged(event)
    {
        if (this._resource.url !== event.data.localResourceOverride.url)
            return;

        if (this._createLocalResourceOverrideButtonNavigationItem)
            this._createLocalResourceOverrideButtonNavigationItem.enabled = WI.networkManager.canBeOverridden(this._resource);
    }

    _mouseWasClicked(event)
    {
        WI.handlePossibleLinkClick(event, this._resource.parentFrame);
    }
};

WI.ResourceContentView.Event = {
    ContentError: "resource-content-view-content-error",
};
