/*
 * 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.RuntimeManager = class RuntimeManager extends WI.Object
{
    constructor()
    {
        super();

        this._activeExecutionContext = null;

        WI.Frame.addEventListener(WI.Frame.Event.ExecutionContextsCleared, this._frameExecutionContextsCleared, this);
    }

    // Static

    static supportsAwaitPromise()
    {
        // COMPATIBILITY (iOS 12): Runtime.awaitPromise did not exist
        return !!InspectorBackend.domains.Runtime.awaitPromise;
    }

    // Target

    initializeTarget(target)
    {
        target.RuntimeAgent.enable();

        // COMPATIBILITY (iOS 8): Runtime.enableTypeProfiler did not exist.
        if (target.RuntimeAgent.enableTypeProfiler && WI.settings.showJavaScriptTypeInformation.value)
            target.RuntimeAgent.enableTypeProfiler();

        // COMPATIBILITY (iOS 10): Runtime.enableControlFlowProfiler did not exist
        if (target.RuntimeAgent.enableControlFlowProfiler && WI.settings.enableControlFlowProfiler.value)
            target.RuntimeAgent.enableControlFlowProfiler();
    }

    // Public

    get activeExecutionContext()
    {
        return this._activeExecutionContext;
    }

    set activeExecutionContext(executionContext)
    {
        if (this._activeExecutionContext === executionContext)
            return;

        this._activeExecutionContext = executionContext;

        this.dispatchEventToListeners(WI.RuntimeManager.Event.ActiveExecutionContextChanged);
    }

    evaluateInInspectedWindow(expression, options, callback)
    {
        if (!this._activeExecutionContext) {
            callback(null, false);
            return;
        }

        let {objectGroup, includeCommandLineAPI, doNotPauseOnExceptionsAndMuteConsole, returnByValue, generatePreview, saveResult, emulateUserGesture, sourceURLAppender} = options;

        includeCommandLineAPI = includeCommandLineAPI || false;
        doNotPauseOnExceptionsAndMuteConsole = doNotPauseOnExceptionsAndMuteConsole || false;
        returnByValue = returnByValue || false;
        generatePreview = generatePreview || false;
        saveResult = saveResult || false;
        emulateUserGesture = emulateUserGesture || false;
        sourceURLAppender = sourceURLAppender || appendWebInspectorSourceURL;

        console.assert(objectGroup, "RuntimeManager.evaluateInInspectedWindow should always be called with an objectGroup");
        console.assert(typeof sourceURLAppender === "function");

        if (!expression) {
            // There is no expression, so the completion should happen against global properties.
            expression = "this";
        } else if (/^\s*\{/.test(expression) && /\}\s*$/.test(expression)) {
            // Transform {a:1} to ({a:1}) so it is treated like an object literal instead of a block with a label.
            expression = "(" + expression + ")";
        } else if (/\bawait\b/.test(expression)) {
            // Transform `await <expr>` into an async function assignment.
            expression = this._tryApplyAwaitConvenience(expression);
        }

        expression = sourceURLAppender(expression);

        let target = this._activeExecutionContext.target;
        let executionContextId = this._activeExecutionContext.id;

        if (WI.debuggerManager.activeCallFrame) {
            target = WI.debuggerManager.activeCallFrame.target;
            executionContextId = target.executionContext.id;
        }

        function evalCallback(error, result, wasThrown, savedResultIndex)
        {
            this.dispatchEventToListeners(WI.RuntimeManager.Event.DidEvaluate, {objectGroup});

            if (error) {
                console.error(error);
                callback(null, false);
                return;
            }

            if (returnByValue)
                callback(null, wasThrown, wasThrown ? null : result, savedResultIndex);
            else
                callback(WI.RemoteObject.fromPayload(result, target), wasThrown, savedResultIndex);
        }

        if (WI.debuggerManager.activeCallFrame) {
            // COMPATIBILITY (iOS 8): "saveResult" did not exist.
            target.DebuggerAgent.evaluateOnCallFrame.invoke({callFrameId: WI.debuggerManager.activeCallFrame.id, expression, objectGroup, includeCommandLineAPI, doNotPauseOnExceptionsAndMuteConsole, returnByValue, generatePreview, saveResult}, evalCallback.bind(this), target.DebuggerAgent);
            return;
        }

        // COMPATIBILITY (iOS 8): "saveResult" did not exist.
        // COMPATIBILITY (iOS 12.2): "emulateUserGesture" did not exist.
        target.RuntimeAgent.evaluate.invoke({expression, objectGroup, includeCommandLineAPI, doNotPauseOnExceptionsAndMuteConsole, contextId: executionContextId, returnByValue, generatePreview, saveResult, emulateUserGesture}, evalCallback.bind(this), target.RuntimeAgent);
    }

    saveResult(remoteObject, callback)
    {
        console.assert(remoteObject instanceof WI.RemoteObject);

        let target = this._activeExecutionContext.target;
        let executionContextId = this._activeExecutionContext.id;

        // COMPATIBILITY (iOS 8): Runtime.saveResult did not exist.
        if (!target.RuntimeAgent.saveResult) {
            callback(undefined);
            return;
        }

        function mycallback(error, savedResultIndex)
        {
            callback(savedResultIndex);
        }

        if (remoteObject.objectId)
            target.RuntimeAgent.saveResult(remoteObject.asCallArgument(), mycallback);
        else
            target.RuntimeAgent.saveResult(remoteObject.asCallArgument(), executionContextId, mycallback);
    }

    getPropertiesForRemoteObject(objectId, callback)
    {
        this._activeExecutionContext.target.RuntimeAgent.getProperties(objectId, function(error, result) {
            if (error) {
                callback(error);
                return;
            }

            let properties = new Map;
            for (let property of result)
                properties.set(property.name, property);

            callback(null, properties);
        });
    }

    // Private

    _frameExecutionContextsCleared(event)
    {
        let contexts = event.data.contexts || [];

        let currentContextWasDestroyed = contexts.some((context) => context.id === this._activeExecutionContext.id);
        if (currentContextWasDestroyed)
            this.activeExecutionContext = WI.mainTarget.executionContext;
    }

    _tryApplyAwaitConvenience(originalExpression)
    {
        let esprimaSyntaxTree;

        // Do not transform if the original code parses just fine.
        try {
            esprima.parse(originalExpression);
            return originalExpression;
        } catch { }

        // Do not transform if the async function version does not parse.
        try {
            esprimaSyntaxTree = esprima.parse("(async function(){" + originalExpression + "})");
        } catch {
            return originalExpression;
        }

        // Assert expected AST produced by our wrapping code.
        console.assert(esprimaSyntaxTree.type === "Program");
        console.assert(esprimaSyntaxTree.body.length === 1);
        console.assert(esprimaSyntaxTree.body[0].type === "ExpressionStatement");
        console.assert(esprimaSyntaxTree.body[0].expression.type === "FunctionExpression");
        console.assert(esprimaSyntaxTree.body[0].expression.async);
        console.assert(esprimaSyntaxTree.body[0].expression.body.type === "BlockStatement");

        // Do not transform if there is more than one statement.
        let asyncFunctionBlock = esprimaSyntaxTree.body[0].expression.body;
        if (asyncFunctionBlock.body.length !== 1)
            return originalExpression;

        // Extract the variable name for transformation.
        let variableName;
        let anonymous = false;
        let declarationKind = "var";
        let awaitPortion;
        let statement = asyncFunctionBlock.body[0];
        if (statement.type === "ExpressionStatement"
            && statement.expression.type === "AwaitExpression") {
            // await <expr>
            anonymous = true;
        } else if (statement.type === "ExpressionStatement"
            && statement.expression.type === "AssignmentExpression"
            && statement.expression.right.type === "AwaitExpression"
            && statement.expression.left.type === "Identifier") {
            // x = await <expr>
            variableName = statement.expression.left.name;
            awaitPortion = originalExpression.substring(originalExpression.indexOf("await"));
        } else if (statement.type === "VariableDeclaration"
            && statement.declarations.length === 1
            && statement.declarations[0].init.type === "AwaitExpression"
            && statement.declarations[0].id.type === "Identifier") {
            // var x = await <expr>
            variableName = statement.declarations[0].id.name;
            declarationKind = statement.kind;
            awaitPortion = originalExpression.substring(originalExpression.indexOf("await"));
        } else {
            // Do not transform if this was not one of the simple supported syntaxes.
            return originalExpression;
        }

        if (anonymous) {
            return `
(async function() {
    try {
        let result = ${originalExpression};
        console.info("%o", result);
    } catch (e) {
        console.error(e);
    }
})();
undefined`;
        }

        return `${declarationKind} ${variableName};
(async function() {
    try {
        ${variableName} = ${awaitPortion};
        console.info("%o", ${variableName});
    } catch (e) {
        console.error(e);
    }
})();
undefined;`;
    }
};

WI.RuntimeManager.ConsoleObjectGroup = "console";
WI.RuntimeManager.TopLevelExecutionContextIdentifier = undefined;

WI.RuntimeManager.Event = {
    DidEvaluate: Symbol("runtime-manager-did-evaluate"),
    DefaultExecutionContextChanged: Symbol("runtime-manager-default-execution-context-changed"),
    ActiveExecutionContextChanged: Symbol("runtime-manager-active-execution-context-changed"),
};
