/*
 * Copyright (C) 2008, 2014 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. ``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
 * 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.
 */

#include "config.h"
#include "ProfileGenerator.h"

#include "CallFrame.h"
#include "CodeBlock.h"
#include "JSGlobalObject.h"
#include "JSStringRef.h"
#include "JSFunction.h"
#include "LegacyProfiler.h"
#include "JSCInlines.h"
#include "Profile.h"
#include "StackVisitor.h"
#include "Tracing.h"

namespace JSC {

PassRefPtr<ProfileGenerator> ProfileGenerator::create(ExecState* exec, const String& title, unsigned uid, PassRefPtr<Stopwatch> stopwatch)
{
    return adoptRef(new ProfileGenerator(exec, title, uid, stopwatch));
}

ProfileGenerator::ProfileGenerator(ExecState* exec, const String& title, unsigned uid, PassRefPtr<Stopwatch> stopwatch)
    : m_origin(exec ? exec->lexicalGlobalObject() : nullptr)
    , m_profileGroup(exec ? exec->lexicalGlobalObject()->profileGroup() : 0)
    , m_stopwatch(stopwatch)
    , m_foundConsoleStartParent(false)
    , m_suspended(false)
{
    m_profile = Profile::create(title, uid);
    m_currentNode = m_rootNode = m_profile->rootNode();
    if (exec)
        addParentForConsoleStart(exec);
}

class AddParentForConsoleStartFunctor {
public:
    AddParentForConsoleStartFunctor(ExecState* exec, RefPtr<ProfileNode>& rootNode, RefPtr<ProfileNode>& currentNode)
        : m_exec(exec)
        , m_hasSkippedFirstFrame(false)
        , m_foundParent(false)
        , m_rootNode(rootNode)
        , m_currentNode(currentNode)
    {
    }

    bool foundParent() const { return m_foundParent; }

    StackVisitor::Status operator()(StackVisitor& visitor)
    {
        if (!m_hasSkippedFirstFrame) {
            m_hasSkippedFirstFrame = true;
            return StackVisitor::Continue;
        }

        unsigned line = 0;
        unsigned column = 0;
        visitor->computeLineAndColumn(line, column);
        m_currentNode = ProfileNode::create(m_exec, LegacyProfiler::createCallIdentifier(m_exec, visitor->callee(), visitor->sourceURL(), line, column), m_rootNode.get());
        // Assume that profile times are relative to when the |console.profile| command is evaluated.
        // This matches the logic in JSStartProfiling() and InspectorTimelineAgent::startFromConsole().
        m_currentNode->appendCall(ProfileNode::Call(0.0));
        m_rootNode->spliceNode(m_currentNode.get());

        m_foundParent = true;
        return StackVisitor::Done;
    }

private:
    ExecState* m_exec;
    bool m_hasSkippedFirstFrame;
    bool m_foundParent;
    RefPtr<ProfileNode>& m_rootNode;
    RefPtr<ProfileNode>& m_currentNode;
};

void ProfileGenerator::addParentForConsoleStart(ExecState* exec)
{
    AddParentForConsoleStartFunctor functor(exec, m_rootNode, m_currentNode);
    exec->iterate(functor);

    m_foundConsoleStartParent = functor.foundParent();
}

const String& ProfileGenerator::title() const
{
    return m_profile->title();
}

void ProfileGenerator::beginCallEntry(ProfileNode* node, double startTime)
{
    ASSERT_ARG(node, node);

    if (std::isnan(startTime))
        startTime = m_stopwatch->elapsedTime();

    node->appendCall(ProfileNode::Call(startTime));
}

void ProfileGenerator::endCallEntry(ProfileNode* node)
{
    ASSERT_ARG(node, node);

    ProfileNode::Call& last = node->lastCall();

    double previousElapsedTime = std::isnan(last.elapsedTime()) ? 0.0 : last.elapsedTime();
    double newlyElapsedTime = m_stopwatch->elapsedTime() - last.startTime();
    last.setElapsedTime(previousElapsedTime + newlyElapsedTime);
}

void ProfileGenerator::willExecute(ExecState* callerCallFrame, const CallIdentifier& callIdentifier)
{
    if (JAVASCRIPTCORE_PROFILE_WILL_EXECUTE_ENABLED()) {
        CString name = callIdentifier.functionName().utf8();
        CString url = callIdentifier.url().utf8();
        JAVASCRIPTCORE_PROFILE_WILL_EXECUTE(m_profileGroup, const_cast<char*>(name.data()), const_cast<char*>(url.data()), callIdentifier.lineNumber(), callIdentifier.columnNumber());
    }

    if (!m_origin)
        return;

    if (m_suspended)
        return;

    RefPtr<ProfileNode> calleeNode = nullptr;

    // Find or create a node for the callee call frame.
    for (const RefPtr<ProfileNode>& child : m_currentNode->children()) {
        if (child->callIdentifier() == callIdentifier)
            calleeNode = child;
    }

    if (!calleeNode) {
        calleeNode = ProfileNode::create(callerCallFrame, callIdentifier, m_currentNode.get());
        m_currentNode->addChild(calleeNode);
    }

    m_currentNode = calleeNode;
    beginCallEntry(calleeNode.get(), m_stopwatch->elapsedTime());
}

void ProfileGenerator::didExecute(ExecState* callerCallFrame, const CallIdentifier& callIdentifier)
{
    if (JAVASCRIPTCORE_PROFILE_DID_EXECUTE_ENABLED()) {
        CString name = callIdentifier.functionName().utf8();
        CString url = callIdentifier.url().utf8();
        JAVASCRIPTCORE_PROFILE_DID_EXECUTE(m_profileGroup, const_cast<char*>(name.data()), const_cast<char*>(url.data()), callIdentifier.lineNumber(), callIdentifier.columnNumber());
    }

    if (!m_origin)
        return;

    if (m_suspended)
        return;

    // Make a new node if the caller node has never seen this callee call frame before.
    // This can happen if |console.profile()| is called several frames deep in the call stack.
    ASSERT(m_currentNode);
    if (m_currentNode->callIdentifier() != callIdentifier) {
        RefPtr<ProfileNode> calleeNode = ProfileNode::create(callerCallFrame, callIdentifier, m_currentNode.get());
        beginCallEntry(calleeNode.get(), m_currentNode->lastCall().startTime());
        endCallEntry(calleeNode.get());
        m_currentNode->spliceNode(calleeNode.release());
        return;
    }

    endCallEntry(m_currentNode.get());
    m_currentNode = m_currentNode->parent();
}

void ProfileGenerator::exceptionUnwind(ExecState* handlerCallFrame, const CallIdentifier&)
{
    // If the current node was called by the handler (==) or any
    // more nested function (>) the we have exited early from it.
    ASSERT(m_currentNode);
    while (m_currentNode->callerCallFrame() >= handlerCallFrame) {
        didExecute(m_currentNode->callerCallFrame(), m_currentNode->callIdentifier());
        ASSERT(m_currentNode);
    }
}

void ProfileGenerator::stopProfiling()
{
    for (ProfileNode* node = m_currentNode.get(); node != m_profile->rootNode(); node = node->parent())
        endCallEntry(node);

    if (m_foundConsoleStartParent) {
        removeProfileStart();
        removeProfileEnd();
    }

    ASSERT(m_currentNode);

    // Set the current node to the parent, because we are in a call that
    // will not get didExecute call.
    m_currentNode = m_currentNode->parent();
}

// The console.profile that started this ProfileGenerator will be the first child.
void ProfileGenerator::removeProfileStart()
{
    ProfileNode* currentNode = nullptr;
    for (ProfileNode* next = m_rootNode.get(); next; next = next->firstChild())
        currentNode = next;

    if (currentNode->callIdentifier().functionName() != "profile")
        return;

    currentNode->parent()->removeChild(currentNode);
}

// The console.profileEnd that stopped this ProfileGenerator will be the last child.
void ProfileGenerator::removeProfileEnd()
{
    ProfileNode* currentNode = nullptr;
    for (ProfileNode* next = m_rootNode.get(); next; next = next->lastChild())
        currentNode = next;

    if (currentNode->callIdentifier().functionName() != "profileEnd")
        return;

    ASSERT(currentNode->callIdentifier() == (currentNode->parent()->children()[currentNode->parent()->children().size() - 1])->callIdentifier());
    currentNode->parent()->removeChild(currentNode);
}

} // namespace JSC
