/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the QtSCriptTools module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this
** file. Please review the following information to ensure the GNU Lesser
** General Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qscriptdebuggeragent_p.h"
#include "qscriptdebuggeragent_p_p.h"
#include "qscriptdebuggerbackend_p_p.h"

#include <QtCore/qcoreapplication.h>
#include <QtCore/qset.h>
#include <QtScript/qscriptengine.h>

QT_BEGIN_NAMESPACE

/*!
  \since 4.5
  \class QScriptDebuggerAgent
  \internal

  This class implements a state machine that uses the low-level events
  reported by the QScriptEngineAgent interface to implement debugging-
  specific functionality such as stepping and breakpoints. It is used
  internally by the QScriptDebuggerBackend class.
*/

QScriptDebuggerAgentPrivate::QScriptDebuggerAgentPrivate()
    : state(NoState), stepDepth(0), stepCount(0),
        targetScriptId(-1), targetLineNumber(-1), returnCounter(0),
        nextBreakpointId(1), hitBreakpointId(0),
        nextContextId(0), statementCounter(0)
{
}

QScriptDebuggerAgentPrivate::~QScriptDebuggerAgentPrivate()
{
}

QScriptDebuggerAgentPrivate *QScriptDebuggerAgentPrivate::get(
    QScriptDebuggerAgent *q)
{
    if (!q)
        return 0;
    return q->d_func();
}


/*!
  Constructs a new agent for the given \a engine. The agent will
  report debugging-related events (e.g. step completion) to the given
  \a backend.
*/
QScriptDebuggerAgent::QScriptDebuggerAgent(
    QScriptDebuggerBackendPrivate *backend, QScriptEngine *engine)
    : QScriptEngineAgent(engine), d_ptr(new QScriptDebuggerAgentPrivate())
{
    Q_D(QScriptDebuggerAgent);
    d->backend = backend;

    QScriptContext *ctx = engine->currentContext();
    while (ctx) {
        d->scriptIdStack.append(QList<qint64>());
        d->contextIdStack.append(d->nextContextId);
        ++d->nextContextId;
        ctx = ctx->parentContext();
    }
}

/*!
  Destroys this QScriptDebuggerAgent.
*/
QScriptDebuggerAgent::~QScriptDebuggerAgent()
{
    Q_D(QScriptDebuggerAgent);
    if (d->backend)
        d->backend->agentDestroyed(this);
    delete d;
}

/*!
  Instructs the agent to perform a "step into" operation.  This
  function returns immediately. The agent will report step completion
  at a later time, i.e. when script statements are evaluated.
*/
void QScriptDebuggerAgent::enterStepIntoMode(int count)
{
    Q_D(QScriptDebuggerAgent);
    d->state = QScriptDebuggerAgentPrivate::SteppingIntoState;
    d->stepCount = count;
    d->stepResult = QScriptValue();
}

/*!
  Instructs the agent to perform a "step over" operation.  This
  function returns immediately. The agent will report step completion
  at a later time, i.e. when script statements are evaluated.
*/
void QScriptDebuggerAgent::enterStepOverMode(int count)
{
    Q_D(QScriptDebuggerAgent);
    d->state = QScriptDebuggerAgentPrivate::SteppingOverState;
    if (engine()->isEvaluating())
        d->stepDepth = 0;
    else
        d->stepDepth = -1;
    d->stepCount = count;
    d->stepResult = QScriptValue();
}

/*!
  Instructs the agent to perform a "step out" operation.  This
  function returns immediately. The agent will report step completion
  at a later time, i.e. when script statements are evaluated.
*/
void QScriptDebuggerAgent::enterStepOutMode()
{
    Q_D(QScriptDebuggerAgent);
    d->state = QScriptDebuggerAgentPrivate::SteppingOutState;
    if (engine()->isEvaluating())
        d->stepDepth = 0;
    else
        d->stepDepth = -1;
}

/*!
  Instructs the agent to continue evaluation.
  This function returns immediately.
*/
void QScriptDebuggerAgent::enterContinueMode()
{
    Q_D(QScriptDebuggerAgent);
    d->state = QScriptDebuggerAgentPrivate::NoState;
}

/*!
  Instructs the agent to interrupt evaluation.
  This function returns immediately.
*/
void QScriptDebuggerAgent::enterInterruptMode()
{
    Q_D(QScriptDebuggerAgent);
    d->state = QScriptDebuggerAgentPrivate::InterruptingState;
}

/*!
  Instructs the agent to continue evaluation until the location
  described by \a fileName and \a lineNumber is reached.  This
  function returns immediately.
*/
void QScriptDebuggerAgent::enterRunToLocationMode(const QString &fileName, int lineNumber)
{
    Q_D(QScriptDebuggerAgent);
    d->targetFileName = fileName;
    d->targetLineNumber = lineNumber;
    d->targetScriptId = resolveScript(fileName);
    d->state = QScriptDebuggerAgentPrivate::RunningToLocationState;
}

/*!
  Instructs the agent to continue evaluation until the location
  described by \a scriptId and \a lineNumber is reached.  This
  function returns immediately.
*/
void QScriptDebuggerAgent::enterRunToLocationMode(qint64 scriptId, int lineNumber)
{
    Q_D(QScriptDebuggerAgent);
    d->targetScriptId = scriptId;
    d->targetFileName = QString();
    d->targetLineNumber = lineNumber;
    d->state = QScriptDebuggerAgentPrivate::RunningToLocationState;
}

void QScriptDebuggerAgent::enterReturnByForceMode(int contextIndex, const QScriptValue &value)
{
    Q_D(QScriptDebuggerAgent);
    d->returnCounter = contextIndex + 1;
    d->returnValue = QScriptValue();
    d->state = QScriptDebuggerAgentPrivate::ReturningByForceState;
    // throw an exception; we will catch it when the proper frame is popped
    engine()->currentContext()->throwValue(value);
}

/*!
  Sets a breakpoint defined by the given \a data.
  Returns an integer that uniquely identifies the new breakpoint,
  or -1 if setting the breakpoint failed.
*/
int QScriptDebuggerAgent::setBreakpoint(const QScriptBreakpointData &data)
{
    Q_D(QScriptDebuggerAgent);
    qint64 scriptId = data.scriptId();
    if (scriptId != -1) {
        if (!d->scripts.contains(scriptId)) {
            // that script has been unloaded, so invalidate the ID
            scriptId = -1;
            const_cast<QScriptBreakpointData&>(data).setScriptId(-1);
        } else if (data.fileName().isEmpty()) {
            QString fileName = d->scripts[scriptId].fileName();
            const_cast<QScriptBreakpointData&>(data).setFileName(fileName);
        }
    }

    int id = d->nextBreakpointId;
    ++d->nextBreakpointId;

    if (scriptId != -1) {
        d->resolvedBreakpoints[scriptId].append(id);
    } else {
        QString fileName = data.fileName();
        bool resolved = false;
        QScriptScriptMap::const_iterator it;
        for (it = d->scripts.constBegin(); it != d->scripts.constEnd(); ++it) {
            if (it.value().fileName() == fileName) {
                d->resolvedBreakpoints[it.key()].append(id);
                resolved = true;
                break;
            }
        }
        if (!resolved)
            d->unresolvedBreakpoints[fileName].append(id);
    }

    d->breakpoints.insert(id, data);

    return id;
}

/*!
  Deletes the breakpoint with the given \a id.
  Returns true if the breakpoint was deleted, false if
  no such breakpoint exists.
*/
bool QScriptDebuggerAgent::deleteBreakpoint(int id)
{
    Q_D(QScriptDebuggerAgent);
    if (!d->breakpoints.contains(id))
        return false;
    d->breakpoints.remove(id);
    bool found = false;
    {
        QHash<qint64, QList<int> >::iterator it;
        it = d->resolvedBreakpoints.begin();
        for ( ; !found && (it != d->resolvedBreakpoints.end()); ) {
            QList<int> &lst = it.value();
            Q_ASSERT(!lst.isEmpty());
            for (int i = 0; i < lst.size(); ++i) {
                if (lst.at(i) == id) {
                    lst.removeAt(i);
                    found = true;
                    break;
                }
            }
            if (lst.isEmpty())
                it = d->resolvedBreakpoints.erase(it);
            else
                ++it;
        }
    }
    if (!found) {
        QHash<QString, QList<int> >::iterator it;
        it = d->unresolvedBreakpoints.begin();
        for ( ; !found && (it != d->unresolvedBreakpoints.end()); ) {
            QList<int> &lst = it.value();
            Q_ASSERT(!lst.isEmpty());
            for (int i = 0; i < lst.size(); ++i) {
                if (lst.at(i) == id) {
                    lst.removeAt(i);
                    found = true;
                    break;
                }
            }
            if (lst.isEmpty())
                it = d->unresolvedBreakpoints.erase(it);
            else
                ++it;
        }
    }
    return found;
}

/*!
  Deletes all breakpoints.
*/
void QScriptDebuggerAgent::deleteAllBreakpoints()
{
    Q_D(QScriptDebuggerAgent);
    d->breakpoints.clear();
    d->resolvedBreakpoints.clear();
    d->unresolvedBreakpoints.clear();
}

/*!
  Returns the data associated with the breakpoint with the given \a
  id.
*/
QScriptBreakpointData QScriptDebuggerAgent::breakpointData(int id) const
{
    Q_D(const QScriptDebuggerAgent);
    return d->breakpoints.value(id);
}

/*!
  Sets the data associated with the breakpoint with the given \a
  id.
*/
bool QScriptDebuggerAgent::setBreakpointData(int id,
                                             const QScriptBreakpointData &data)
{
    Q_D(QScriptDebuggerAgent);
    if (!d->breakpoints.contains(id))
        return false;
    d->breakpoints[id] = data;
    return true;
}

/*!
  Returns all breakpoints.
*/
QScriptBreakpointMap QScriptDebuggerAgent::breakpoints() const
{
    Q_D(const QScriptDebuggerAgent);
    return d->breakpoints;
}

/*!
  Returns all scripts.
*/
QScriptScriptMap QScriptDebuggerAgent::scripts() const
{
    Q_D(const QScriptDebuggerAgent);
    return d->scripts;
}

/*!
  Returns the data associated with the script with the given \a id.
*/
QScriptScriptData QScriptDebuggerAgent::scriptData(qint64 id) const
{
    Q_D(const QScriptDebuggerAgent);
    return d->scripts.value(id);
}

/*!
  Checkpoints the current scripts.
*/
void QScriptDebuggerAgent::scriptsCheckpoint()
{
    Q_D(QScriptDebuggerAgent);
    d->previousCheckpointScripts = d->checkpointScripts;
    d->checkpointScripts = d->scripts;
}

/*!
  Returns the difference between the current checkpoint and the
  previous checkpoint. The first item in the pair is a list containing
  the identifiers of the scripts that were added. The second item in
  the pair is a list containing the identifiers of the scripts that
  were removed.
*/
QPair<QList<qint64>, QList<qint64> > QScriptDebuggerAgent::scriptsDelta() const
{
    Q_D(const QScriptDebuggerAgent);
    QSet<qint64> prevSet = d->previousCheckpointScripts.keys().toSet();
    QSet<qint64> currSet = d->checkpointScripts.keys().toSet();
    QSet<qint64> addedScriptIds = currSet - prevSet;
    QSet<qint64> removedScriptIds = prevSet - currSet;
    return qMakePair(addedScriptIds.toList(), removedScriptIds.toList());
}

/*!
  Returns the identifier of the script that has the given \a fileName,
  or -1 if there is no such script.
*/
qint64 QScriptDebuggerAgent::resolveScript(const QString &fileName) const
{
    Q_D(const QScriptDebuggerAgent);
    QScriptScriptMap::const_iterator it;
    for (it = d->scripts.constBegin(); it != d->scripts.constEnd(); ++it) {
        if (it.value().fileName() == fileName)
            return it.key();
    }
    return -1;
}

QList<qint64> QScriptDebuggerAgent::contextIds() const
{
    Q_D(const QScriptDebuggerAgent);
    return d->contextIdStack;
}

QPair<QList<qint64>, QList<qint64> > QScriptDebuggerAgent::contextsCheckpoint()
{
    Q_D(QScriptDebuggerAgent);
    int i = d->checkpointContextIdStack.size() - 1;
    int j = d->contextIdStack.size() - 1;
    for ( ; (i >= 0) && (j >= 0); --i, --j) {
        if (d->checkpointContextIdStack.at(i) != d->contextIdStack.at(j))
            break;
    }
    QList<qint64> removed = d->checkpointContextIdStack.mid(0, i+1);
    QList<qint64> added = d->contextIdStack.mid(0, j+1);
    d->checkpointContextIdStack = d->contextIdStack;
    return qMakePair(removed, added);
}

void QScriptDebuggerAgent::nullifyBackendPointer()
{
    Q_D(QScriptDebuggerAgent);
    d->backend = 0;
}

/*!
  \reimp
*/
void QScriptDebuggerAgent::scriptLoad(qint64 id, const QString &program,
                                      const QString &fileName, int baseLineNumber)
{
    Q_D(QScriptDebuggerAgent);
    QScriptScriptData data = QScriptScriptData(program, fileName, baseLineNumber);
    d->scripts.insert(id, data);

    if ((d->state == QScriptDebuggerAgentPrivate::RunningToLocationState)
        && (d->targetScriptId == -1)
        && ((d->targetFileName == fileName) || d->targetFileName.isEmpty())) {
        d->targetScriptId = id;
    }

    if (!fileName.isEmpty()) {
        QList<int> lst = d->unresolvedBreakpoints.take(fileName);
        if (!lst.isEmpty())
            d->resolvedBreakpoints.insert(id, lst);
    }
}

/*!
  \reimp
*/
void QScriptDebuggerAgent::scriptUnload(qint64 id)
{
    Q_D(QScriptDebuggerAgent);
    QScriptScriptData data = d->scripts.take(id);
    QString fileName = data.fileName();

    if ((d->state == QScriptDebuggerAgentPrivate::RunningToLocationState)
        && (d->targetScriptId == id)) {
        d->targetScriptId = -1;
        d->targetFileName = fileName;
    }

    if (!fileName.isEmpty()) {
        QList<int> lst = d->resolvedBreakpoints.take(id);
        if (!lst.isEmpty())
            d->unresolvedBreakpoints.insert(fileName, lst);
    }
}

/*!
  \reimp
*/
void QScriptDebuggerAgent::contextPush()
{
    Q_D(QScriptDebuggerAgent);
    d->scriptIdStack.append(QList<qint64>());
    d->contextIdStack.prepend(d->nextContextId);
    ++d->nextContextId;
}

/*!
  \reimp
*/
void QScriptDebuggerAgent::contextPop()
{
    Q_D(QScriptDebuggerAgent);
    d->scriptIdStack.removeLast();
    d->contextIdStack.removeFirst();
}

/*!
  \reimp
*/
void QScriptDebuggerAgent::functionEntry(qint64 scriptId)
{
    Q_D(QScriptDebuggerAgent);
    QList<qint64> &ids = d->scriptIdStack.last();
    ids.append(scriptId);
    if ((d->state == QScriptDebuggerAgentPrivate::SteppingOverState)
        || (d->state == QScriptDebuggerAgentPrivate::SteppingOutState)) {
        ++d->stepDepth;
    }
}

/*!
  \reimp
*/
void QScriptDebuggerAgent::functionExit(qint64 scriptId,
                                        const QScriptValue &returnValue)
{
    Q_UNUSED(scriptId);
    Q_D(QScriptDebuggerAgent);
    QList<qint64> &ids = d->scriptIdStack.last();
    ids.removeLast();
    if (d->state == QScriptDebuggerAgentPrivate::SteppingOverState) {
        --d->stepDepth;
    } else if (d->state == QScriptDebuggerAgentPrivate::SteppingOutState) {
        if (--d->stepDepth < 0) {
            d->stepResult = returnValue;
            d->state = QScriptDebuggerAgentPrivate::SteppedOutState;
        }
    } else if (d->state == QScriptDebuggerAgentPrivate::ReturningByForceState) {
        if (--d->returnCounter == 0) {
            d->returnValue = returnValue;
            d->state = QScriptDebuggerAgentPrivate::ReturnedByForceState;
            engine()->clearExceptions();
        }
    }
}

/*!
  \reimp
*/
void QScriptDebuggerAgent::positionChange(qint64 scriptId,
                                          int lineNumber, int columnNumber)
{
    Q_D(QScriptDebuggerAgent);
    if (engine()->processEventsInterval() == -1) {
        // see if it's time to call processEvents()
        if ((++d->statementCounter % 25000) == 0) {
            if (!d->processEventsTimer.isNull()) {
                if (d->processEventsTimer.elapsed() > 30) {
                    QCoreApplication::processEvents();
                    d->processEventsTimer.restart();
                }
            } else {
                d->processEventsTimer.start();
            }
        }
    }

    // check breakpoints
    {
        QList<int> lst = d->resolvedBreakpoints.value(scriptId);
        for (int i = 0; i < lst.size(); ++i) {
            int id = lst.at(i);
            QScriptBreakpointData &data = d->breakpoints[id];
            if (!data.isEnabled())
                continue;
            if (data.lineNumber() != lineNumber)
                continue;
            if (!data.condition().isEmpty()) {
                // ### careful, evaluate() can cause an exception
                // ### disable callbacks in nested evaluate?
                QScriptDebuggerAgentPrivate::State was = d->state;
                d->state = QScriptDebuggerAgentPrivate::NoState;
                QScriptValue ret = engine()->evaluate(
                    data.condition(),
                    QString::fromLatin1("Breakpoint %0 condition checker").arg(id));
                if (!ret.isError())
                    d->state = was;
                if (!ret.toBoolean())
                    continue;
            }
            if (!data.hit())
                continue;
            d->hitBreakpointId = id;
            d->state = QScriptDebuggerAgentPrivate::BreakpointState;
        }
    }

    switch (d->state) {
    case QScriptDebuggerAgentPrivate::NoState:
    case QScriptDebuggerAgentPrivate::SteppingOutState:
    case QScriptDebuggerAgentPrivate::ReturningByForceState:
        // Do nothing
        break;

    case QScriptDebuggerAgentPrivate::SteppingIntoState:
        if (--d->stepCount == 0) {
            d->state = QScriptDebuggerAgentPrivate::NoState;
            if (d->backend)
                d->backend->stepped(scriptId, lineNumber, columnNumber, QScriptValue());
        }
        break;

    case QScriptDebuggerAgentPrivate::SteppingOverState:
        if ((d->stepDepth > 0) || (--d->stepCount != 0))
            break;
        // fallthrough
    case QScriptDebuggerAgentPrivate::SteppedOverState:
        d->state = QScriptDebuggerAgentPrivate::NoState;
        if (d->backend)
            d->backend->stepped(scriptId, lineNumber, columnNumber, d->stepResult);
        break;

    case QScriptDebuggerAgentPrivate::SteppedOutState:
        d->state = QScriptDebuggerAgentPrivate::NoState;
        if (d->backend)
            d->backend->stepped(scriptId, lineNumber, columnNumber, d->stepResult);
        break;

    case QScriptDebuggerAgentPrivate::RunningToLocationState:
        if (((lineNumber == d->targetLineNumber) || (d->targetLineNumber == -1))
            && (scriptId == d->targetScriptId)) {
            d->state = QScriptDebuggerAgentPrivate::NoState;
            if (d->backend)
                d->backend->locationReached(scriptId, lineNumber, columnNumber);
        }
        break;

    case QScriptDebuggerAgentPrivate::InterruptingState:
        d->state = QScriptDebuggerAgentPrivate::NoState;
        if (d->backend)
            d->backend->interrupted(scriptId, lineNumber, columnNumber);
        break;

    case QScriptDebuggerAgentPrivate::BreakpointState:
        d->state = QScriptDebuggerAgentPrivate::NoState;
        if (d->backend)
            d->backend->breakpoint(scriptId, lineNumber, columnNumber, d->hitBreakpointId);
        if (d->breakpoints.value(d->hitBreakpointId).isSingleShot())
            deleteBreakpoint(d->hitBreakpointId);
        break;

    case QScriptDebuggerAgentPrivate::ReturnedByForceState:
        d->state = QScriptDebuggerAgentPrivate::NoState;
        if (d->backend)
            d->backend->forcedReturn(scriptId, lineNumber, columnNumber, d->returnValue);
        break;

    case QScriptDebuggerAgentPrivate::SteppedIntoState:
    case QScriptDebuggerAgentPrivate::ReachedLocationState:
    case QScriptDebuggerAgentPrivate::InterruptedState:
// ### deal with the case when code is evaluated while we're already paused
//        Q_ASSERT(false);
        break;
    }
}

/*!
  \reimp
*/
void QScriptDebuggerAgent::exceptionThrow(qint64 scriptId,
                                          const QScriptValue &exception,
                                          bool hasHandler)
{
    Q_D(QScriptDebuggerAgent);
    if (d->state == QScriptDebuggerAgentPrivate::ReturningByForceState) {
        // we threw this exception ourselves, so ignore it for now
        // (see functionExit()).
        return;
    }
    if (d->backend)
        d->backend->exception(scriptId, exception, hasHandler);
}

/*!
  \reimp
*/
void QScriptDebuggerAgent::exceptionCatch(qint64 scriptId,
                                          const QScriptValue &exception)
{
    Q_UNUSED(scriptId);
    Q_UNUSED(exception);
}

/*!
  \reimp
*/
bool QScriptDebuggerAgent::supportsExtension(Extension extension) const
{
    return (extension == DebuggerInvocationRequest);
}

/*!
  \reimp
*/
QVariant QScriptDebuggerAgent::extension(Extension extension,
                                         const QVariant &argument)
{
    Q_UNUSED(extension);
    Q_D(QScriptDebuggerAgent);
    Q_ASSERT(extension == DebuggerInvocationRequest);
    QVariantList lst = argument.toList();
    qint64 scriptId = lst.at(0).toLongLong();
    int lineNumber = lst.at(1).toInt();
    int columnNumber = lst.at(2).toInt();
    d->state = QScriptDebuggerAgentPrivate::NoState;
    if (d->backend) {
        d->backend->debuggerInvocationRequest(
            scriptId, lineNumber, columnNumber);
    }
    return QVariant();
}

QT_END_NAMESPACE
