/*
 * 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.CallFrame = class CallFrame
{
    constructor(target, id, sourceCodeLocation, functionName, thisObject, scopeChain, nativeCode, programCode, isTailDeleted)
    {
        console.assert(target instanceof WI.Target);
        console.assert(!sourceCodeLocation || sourceCodeLocation instanceof WI.SourceCodeLocation);
        console.assert(!thisObject || thisObject instanceof WI.RemoteObject);
        console.assert(!scopeChain || scopeChain instanceof Array);

        this._isConsoleEvaluation = sourceCodeLocation && isWebInspectorConsoleEvaluationScript(sourceCodeLocation.sourceCode.sourceURL);
        if (this._isConsoleEvaluation) {
            functionName = WI.UIString("Console Evaluation");
            programCode = true;
        }

        this._target = target;
        this._id = id || null;
        this._sourceCodeLocation = sourceCodeLocation || null;
        this._functionName = functionName || "";
        this._thisObject = thisObject || null;
        this._scopeChain = scopeChain || [];
        this._nativeCode = nativeCode || false;
        this._programCode = programCode || false;
        this._isTailDeleted = isTailDeleted || false;
    }

    // Public

    get target() { return this._target; }
    get id() { return this._id; }
    get sourceCodeLocation() { return this._sourceCodeLocation; }
    get functionName() { return this._functionName; }
    get nativeCode() { return this._nativeCode; }
    get programCode() { return this._programCode; }
    get thisObject() { return this._thisObject; }
    get scopeChain() { return this._scopeChain; }
    get isTailDeleted() { return this._isTailDeleted; }
    get isConsoleEvaluation() { return this._isConsoleEvaluation; }

    saveIdentityToCookie()
    {
        // Do nothing. The call frame is torn down when the inspector closes, and
        // we shouldn't restore call frame content views across debugger pauses.
    }

    collectScopeChainVariableNames(callback)
    {
        var result = {this: true, __proto__: null};

        var pendingRequests = this._scopeChain.length;

        function propertiesCollected(properties)
        {
            for (var i = 0; properties && i < properties.length; ++i)
                result[properties[i].name] = true;

            if (--pendingRequests)
                return;

            callback(result);
        }

        for (var i = 0; i < this._scopeChain.length; ++i)
            this._scopeChain[i].objects[0].deprecatedGetAllProperties(propertiesCollected);
    }

    mergedScopeChain()
    {
        let mergedScopes = [];

        // Scopes list goes from top/local (1) to bottom/global (5)
        //   [scope1, scope2, scope3, scope4, scope5]
        let scopes = this._scopeChain.slice();

        // Merge similiar scopes. Some function call frames may have multiple
        // top level closure scopes (one for `var`s one for `let`s) that can be
        // combined to a single scope of variables. Go in reverse order so we
        // merge the first two closure scopes with the same name. Also mark
        // the first time we see a new name, so we know the base for the name.
        //   [scope1&2, scope3, scope4, scope5]
        //      foo      bar     GLE    global
        let lastMarkedHash = null;
        function markAsBaseIfNeeded(scope) {
            if (!scope.hash)
                return false;
            if (scope.type !== WI.ScopeChainNode.Type.Closure)
                return false;
            if (scope.hash === lastMarkedHash)
                return false;
            lastMarkedHash = scope.hash;
            scope.__baseClosureScope = true;
            return true;
        }

        function shouldMergeClosureScopes(youngScope, oldScope, lastMerge) {
            if (!youngScope || !oldScope)
                return false;

            // Don't merge unknown locations.
            if (!youngScope.hash || !oldScope.hash)
                return false;

            // Only merge closure scopes.
            if (youngScope.type !== WI.ScopeChainNode.Type.Closure)
                return false;
            if (oldScope.type !== WI.ScopeChainNode.Type.Closure)
                return false;

            // Don't merge if they are not the same.
            if (youngScope.hash !== oldScope.hash)
                return false;

            // Don't merge if there was already a merge.
            if (lastMerge && youngScope.hash === lastMerge.hash)
                return false;

            return true;
        }

        let lastScope = null;
        let lastMerge = null;
        for (let i = scopes.length - 1; i >= 0; --i) {
            let scope = scopes[i];
            markAsBaseIfNeeded(scope);
            if (shouldMergeClosureScopes(scope, lastScope, lastMerge)) {
                console.assert(lastScope.__baseClosureScope);
                let type = WI.ScopeChainNode.Type.Closure;
                let objects = lastScope.objects.concat(scope.objects);
                let merged = new WI.ScopeChainNode(type, objects, scope.name, scope.location);
                merged.__baseClosureScope = true;
                console.assert(objects.length === 2);

                mergedScopes.pop(); // Remove the last.
                mergedScopes.push(merged); // Add the merged scope.

                lastMerge = merged;
                lastScope = null;
            } else {
                mergedScopes.push(scope);

                lastMerge = null;
                lastScope = scope;
            }
        }

        mergedScopes = mergedScopes.reverse();

        // Mark the first Closure as Local if the name matches this call frame.
        for (let scope of mergedScopes) {
            if (scope.type === WI.ScopeChainNode.Type.Closure) {
                if (scope.name === this._functionName)
                    scope.convertToLocalScope();
                break;
            }
        }

        return mergedScopes;
    }

    // Static

    static functionNameFromPayload(payload)
    {
        let functionName = payload.functionName;
        if (functionName === "global code")
            return WI.UIString("Global Code");
        if (functionName === "eval code")
            return WI.UIString("Eval Code");
        if (functionName === "module code")
            return WI.UIString("Module Code");
        return functionName;
    }

    static programCodeFromPayload(payload)
    {
        return payload.functionName.endsWith(" code");
    }

    static fromDebuggerPayload(target, payload, scopeChain, sourceCodeLocation)
    {
        let id = payload.callFrameId;
        let thisObject = WI.RemoteObject.fromPayload(payload.this, target);
        let functionName = WI.CallFrame.functionNameFromPayload(payload);
        let nativeCode = false;
        let programCode = WI.CallFrame.programCodeFromPayload(payload);
        let isTailDeleted = payload.isTailDeleted;
        return new WI.CallFrame(target, id, sourceCodeLocation, functionName, thisObject, scopeChain, nativeCode, programCode, isTailDeleted);
    }

    static fromPayload(target, payload)
    {
        console.assert(payload);

        let {url, scriptId} = payload;
        let nativeCode = false;
        let sourceCodeLocation = null;
        let functionName = WI.CallFrame.functionNameFromPayload(payload);
        let programCode = WI.CallFrame.programCodeFromPayload(payload);

        if (url === "[native code]") {
            nativeCode = true;
            url = null;
        } else if (url || scriptId) {
            let sourceCode = null;
            if (scriptId) {
                sourceCode = WI.debuggerManager.scriptForIdentifier(scriptId, target);
                if (sourceCode && sourceCode.resource)
                    sourceCode = sourceCode.resource;
            }
            if (!sourceCode)
                sourceCode = WI.frameResourceManager.resourceForURL(url);
            if (!sourceCode)
                sourceCode = WI.debuggerManager.scriptsForURL(url, target)[0];

            if (sourceCode) {
                // The lineNumber is 1-based, but we expect 0-based.
                let lineNumber = payload.lineNumber - 1;
                sourceCodeLocation = sourceCode.createLazySourceCodeLocation(lineNumber, payload.columnNumber);
            } else {
                // Treat this as native code if we were unable to find a source.
                console.assert(!url, "We should have detected source code for something with a url");
                nativeCode = true;
                url = null;
            }
        }

        const id = null;
        const thisObject = null;
        const scopeChain = null;
        const isTailDeleted = false;
        return new WI.CallFrame(target, id, sourceCodeLocation, functionName, thisObject, scopeChain, nativeCode, programCode, isTailDeleted);
    }
};
