/*
 * 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.settings.consoleSavedResultAlias.addEventListener(WI.Setting.Event.Changed, (event) => {
            for (let target of WI.targets) {
                // COMPATIBILITY (iOS 12.2): Runtime.setSavedResultAlias did not exist.
                if (target.hasCommand("Runtime.setSavedResultAlias"))
                    target.RuntimeAgent.setSavedResultAlias(WI.settings.consoleSavedResultAlias.value);
            }
        });

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

    // Static

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

    static preferredSavedResultPrefix()
    {
        // COMPATIBILITY (iOS 12.2): Runtime.setSavedResultAlias did not exist.
        if (!InspectorBackend.hasCommand("Runtime.setSavedResultAlias"))
            return "$";
        return WI.settings.consoleSavedResultAlias.value || "$";
    }

    // Target

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

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

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

        // COMPATIBILITY (iOS 12.2): Runtime.setSavedResultAlias did not exist.
        if (target.hasCommand("Runtime.setSavedResultAlias") && WI.settings.consoleSavedResultAlias.value)
            target.RuntimeAgent.setSavedResultAlias(WI.settings.consoleSavedResultAlias.value);
    }

    // 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.
            // COMPATIBILITY (iOS 13): "emulateUserGesture" did not exist.
            target.DebuggerAgent.evaluateOnCallFrame.invoke({callFrameId: WI.debuggerManager.activeCallFrame.id, expression, objectGroup, includeCommandLineAPI, doNotPauseOnExceptionsAndMuteConsole, returnByValue, generatePreview, saveResult, emulateUserGesture}, evalCallback.bind(this));
            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));
    }

    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.hasCommand("Runtime.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);
    }

    // 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"),
};
