/*
 * Copyright (C) 2013 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.Frame = class Frame extends WI.Object
{
    constructor(id, name, securityOrigin, loaderIdentifier, mainResource)
    {
        super();

        console.assert(id);

        this._id = id;

        this._name = null;
        this._securityOrigin = null;

        this._resourceCollection = new WI.ResourceCollection;
        this._provisionalResourceCollection = new WI.ResourceCollection;
        this._extraScriptCollection = new WI.ScriptCollection;

        this._childFrameCollection = new WI.FrameCollection;
        this._childFrameIdentifierMap = new Map;

        this._parentFrame = null;
        this._isMainFrame = false;

        this._domContentReadyEventTimestamp = NaN;
        this._loadEventTimestamp = NaN;

        this._executionContextList = new WI.ExecutionContextList;

        this.initialize(name, securityOrigin, loaderIdentifier, mainResource);
    }

    // Public

    get resourceCollection() { return this._resourceCollection; }
    get extraScriptCollection() { return this._extraScriptCollection; }
    get childFrameCollection() { return this._childFrameCollection; }

    initialize(name, securityOrigin, loaderIdentifier, mainResource)
    {
        console.assert(loaderIdentifier);
        console.assert(mainResource);

        var oldName = this._name;
        var oldSecurityOrigin = this._securityOrigin;
        var oldMainResource = this._mainResource;

        this._name = name || null;
        this._securityOrigin = securityOrigin || null;
        this._loaderIdentifier = loaderIdentifier || null;

        this._mainResource = mainResource;
        this._mainResource._parentFrame = this;

        if (oldMainResource && this._mainResource !== oldMainResource)
            this._disassociateWithResource(oldMainResource);

        this.removeAllResources();
        this.removeAllChildFrames();
        this.clearExecutionContexts();
        this.clearProvisionalLoad();

        if (this._mainResource !== oldMainResource)
            this._dispatchMainResourceDidChangeEvent(oldMainResource);

        if (this._securityOrigin !== oldSecurityOrigin)
            this.dispatchEventToListeners(WI.Frame.Event.SecurityOriginDidChange, {oldSecurityOrigin});

        if (this._name !== oldName)
            this.dispatchEventToListeners(WI.Frame.Event.NameDidChange, {oldName});
    }

    startProvisionalLoad(provisionalMainResource)
    {
        console.assert(provisionalMainResource);

        this._provisionalMainResource = provisionalMainResource;
        this._provisionalMainResource._parentFrame = this;

        this._provisionalLoaderIdentifier = provisionalMainResource.loaderIdentifier;

        this._provisionalResourceCollection.clear();

        this.dispatchEventToListeners(WI.Frame.Event.ProvisionalLoadStarted);
    }

    commitProvisionalLoad(securityOrigin)
    {
        console.assert(this._provisionalMainResource);
        console.assert(this._provisionalLoaderIdentifier);
        if (!this._provisionalLoaderIdentifier)
            return;

        var oldSecurityOrigin = this._securityOrigin;
        var oldMainResource = this._mainResource;

        this._securityOrigin = securityOrigin || null;
        this._loaderIdentifier = this._provisionalLoaderIdentifier;
        this._mainResource = this._provisionalMainResource;

        this._domContentReadyEventTimestamp = NaN;
        this._loadEventTimestamp = NaN;

        if (oldMainResource && this._mainResource !== oldMainResource)
            this._disassociateWithResource(oldMainResource);

        this.removeAllResources();

        this._resourceCollection = this._provisionalResourceCollection;
        this._provisionalResourceCollection = new WI.ResourceCollection;
        this._extraScriptCollection.clear();

        this.clearExecutionContexts(true);
        this.clearProvisionalLoad(true);
        this.removeAllChildFrames();

        this.dispatchEventToListeners(WI.Frame.Event.ProvisionalLoadCommitted);

        if (this._mainResource !== oldMainResource)
            this._dispatchMainResourceDidChangeEvent(oldMainResource);

        if (this._securityOrigin !== oldSecurityOrigin)
            this.dispatchEventToListeners(WI.Frame.Event.SecurityOriginDidChange, {oldSecurityOrigin});
    }

    clearProvisionalLoad(skipProvisionalLoadClearedEvent)
    {
        if (!this._provisionalLoaderIdentifier)
            return;

        this._provisionalLoaderIdentifier = null;
        this._provisionalMainResource = null;
        this._provisionalResourceCollection.clear();

        if (!skipProvisionalLoadClearedEvent)
            this.dispatchEventToListeners(WI.Frame.Event.ProvisionalLoadCleared);
    }

    get id()
    {
        return this._id;
    }

    get loaderIdentifier()
    {
        return this._loaderIdentifier;
    }

    get provisionalLoaderIdentifier()
    {
        return this._provisionalLoaderIdentifier;
    }

    get name()
    {
        return this._name;
    }

    get securityOrigin()
    {
        return this._securityOrigin;
    }

    get url()
    {
        return this._mainResource._url;
    }

    get domTree()
    {
        if (!this._domTree)
            this._domTree = new WI.DOMTree(this);
        return this._domTree;
    }

    get pageExecutionContext()
    {
        return this._executionContextList.pageExecutionContext;
    }

    get executionContextList()
    {
        return this._executionContextList;
    }

    clearExecutionContexts(committingProvisionalLoad)
    {
        if (this._executionContextList.contexts.length) {
            let contexts = this._executionContextList.contexts.slice();
            this._executionContextList.clear();
            this.dispatchEventToListeners(WI.Frame.Event.ExecutionContextsCleared, {committingProvisionalLoad: !!committingProvisionalLoad, contexts});
        }
    }

    addExecutionContext(context)
    {
        var changedPageContext = this._executionContextList.add(context);

        if (changedPageContext)
            this.dispatchEventToListeners(WI.Frame.Event.PageExecutionContextChanged);
    }

    get mainResource()
    {
        return this._mainResource;
    }

    get provisionalMainResource()
    {
        return this._provisionalMainResource;
    }

    get parentFrame()
    {
        return this._parentFrame;
    }

    get domContentReadyEventTimestamp()
    {
        return this._domContentReadyEventTimestamp;
    }

    get loadEventTimestamp()
    {
        return this._loadEventTimestamp;
    }

    isMainFrame()
    {
        return this._isMainFrame;
    }

    markAsMainFrame()
    {
        this._isMainFrame = true;
    }

    unmarkAsMainFrame()
    {
        this._isMainFrame = false;
    }

    markDOMContentReadyEvent(timestamp)
    {
        this._domContentReadyEventTimestamp = timestamp || NaN;
    }

    markLoadEvent(timestamp)
    {
        this._loadEventTimestamp = timestamp || NaN;
    }

    isDetached()
    {
        var frame = this;
        while (frame) {
            if (frame.isMainFrame())
                return false;
            frame = frame.parentFrame;
        }

        return true;
    }

    childFrameForIdentifier(frameId)
    {
        return this._childFrameIdentifierMap.get(frameId) || null;
    }

    addChildFrame(frame)
    {
        console.assert(frame instanceof WI.Frame);
        if (!(frame instanceof WI.Frame))
            return;

        if (frame._parentFrame === this)
            return;

        if (frame._parentFrame)
            frame._parentFrame.removeChildFrame(frame);

        this._childFrameCollection.add(frame);
        this._childFrameIdentifierMap.set(frame._id, frame);

        frame._parentFrame = this;

        this.dispatchEventToListeners(WI.Frame.Event.ChildFrameWasAdded, {childFrame: frame});
    }

    removeChildFrame(frameOrFrameId)
    {
        console.assert(frameOrFrameId);

        let childFrameId = frameOrFrameId;
        if (childFrameId instanceof WI.Frame)
            childFrameId = frameOrFrameId._id;

        // Fetch the frame by id even if we were passed a WI.Frame.
        // We do this incase the WI.Frame is a new object that isn't
        // in _childFrameCollection, but the id is a valid child frame.
        let childFrame = this.childFrameForIdentifier(childFrameId);
        console.assert(childFrame instanceof WI.Frame);
        if (!(childFrame instanceof WI.Frame))
            return;

        console.assert(childFrame.parentFrame === this);

        this._childFrameCollection.remove(childFrame);
        this._childFrameIdentifierMap.delete(childFrame._id);

        childFrame._detachFromParentFrame();

        this.dispatchEventToListeners(WI.Frame.Event.ChildFrameWasRemoved, {childFrame});
    }

    removeAllChildFrames()
    {
        this._detachFromParentFrame();

        for (let childFrame of this._childFrameCollection.items)
            childFrame.removeAllChildFrames();

        this._childFrameCollection.clear();
        this._childFrameIdentifierMap.clear();

        this.dispatchEventToListeners(WI.Frame.Event.AllChildFramesRemoved);
    }

    resourceForURL(url, recursivelySearchChildFrames)
    {
        var resource = this._resourceCollection.resourceForURL(url);
        if (resource)
            return resource;

        // Check the main resources of the child frames for the requested URL.
        for (let childFrame of this._childFrameCollection.items) {
            resource = childFrame.mainResource;
            if (resource.url === url)
                return resource;
        }

        if (!recursivelySearchChildFrames)
            return null;

        // Recursively search resources of child frames.
        for (let childFrame of this._childFrameCollection.items) {
            resource = childFrame.resourceForURL(url, true);
            if (resource)
                return resource;
        }

        return null;
    }

    resourceCollectionForType(type)
    {
        return this._resourceCollection.resourceCollectionForType(type);
    }

    addResource(resource)
    {
        console.assert(resource instanceof WI.Resource);
        if (!(resource instanceof WI.Resource))
            return;

        if (resource.parentFrame === this)
            return;

        if (resource.parentFrame)
            resource.parentFrame.remove(resource);

        this._associateWithResource(resource);

        if (this._isProvisionalResource(resource)) {
            this._provisionalResourceCollection.add(resource);
            this.dispatchEventToListeners(WI.Frame.Event.ProvisionalResourceWasAdded, {resource});
        } else {
            this._resourceCollection.add(resource);
            this.dispatchEventToListeners(WI.Frame.Event.ResourceWasAdded, {resource});
        }
    }

    removeResource(resource)
    {
        // This does not remove provisional resources.

        this._resourceCollection.remove(resource);

        this._disassociateWithResource(resource);

        this.dispatchEventToListeners(WI.Frame.Event.ResourceWasRemoved, {resource});
    }

    removeAllResources()
    {
        // This does not remove provisional resources, use clearProvisionalLoad for that.

        let resources = this._resourceCollection.items;
        if (!resources.size)
            return;

        for (let resource of resources)
            this._disassociateWithResource(resource);

        this._resourceCollection.clear();

        this.dispatchEventToListeners(WI.Frame.Event.AllResourcesRemoved);
    }

    addExtraScript(script)
    {
        this._extraScriptCollection.add(script);

        this.dispatchEventToListeners(WI.Frame.Event.ExtraScriptAdded, {script});
    }

    saveIdentityToCookie(cookie)
    {
        cookie[WI.Frame.MainResourceURLCookieKey] = this.mainResource.url.hash;
        cookie[WI.Frame.IsMainFrameCookieKey] = this._isMainFrame;
    }

    // Private

    _detachFromParentFrame()
    {
        if (this._domTree) {
            this._domTree.disconnect();
            this._domTree = null;
        }

        this._parentFrame = null;
    }

    _isProvisionalResource(resource)
    {
        return resource.loaderIdentifier && this._provisionalLoaderIdentifier && resource.loaderIdentifier === this._provisionalLoaderIdentifier;
    }

    _associateWithResource(resource)
    {
        console.assert(!resource._parentFrame);
        if (resource._parentFrame)
            return;

        resource._parentFrame = this;
    }

    _disassociateWithResource(resource)
    {
        console.assert(resource.parentFrame === this);
        if (resource.parentFrame !== this)
            return;

        resource._parentFrame = null;
    }

    _dispatchMainResourceDidChangeEvent(oldMainResource)
    {
        this.dispatchEventToListeners(WI.Frame.Event.MainResourceDidChange, {oldMainResource});
    }
};

WI.Frame.Event = {
    NameDidChange: "frame-name-did-change",
    SecurityOriginDidChange: "frame-security-origin-did-change",
    MainResourceDidChange: "frame-main-resource-did-change",
    ProvisionalLoadStarted: "frame-provisional-load-started",
    ProvisionalLoadCommitted: "frame-provisional-load-committed",
    ProvisionalLoadCleared: "frame-provisional-load-cleared",
    ProvisionalResourceWasAdded: "frame-provisional-resource-was-added",
    ResourceWasAdded: "frame-resource-was-added",
    ResourceWasRemoved: "frame-resource-was-removed",
    AllResourcesRemoved: "frame-all-resources-removed",
    ExtraScriptAdded: "frame-extra-script-added",
    ChildFrameWasAdded: "frame-child-frame-was-added",
    ChildFrameWasRemoved: "frame-child-frame-was-removed",
    AllChildFramesRemoved: "frame-all-child-frames-removed",
    PageExecutionContextChanged: "frame-page-execution-context-changed",
    ExecutionContextsCleared: "frame-execution-contexts-cleared"
};

WI.Frame.TypeIdentifier = "Frame";
WI.Frame.MainResourceURLCookieKey = "frame-main-resource-url";
WI.Frame.IsMainFrameCookieKey = "frame-is-main-frame";
