/****************************************************************************
**
** 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 "qscriptdebuggercommandexecutor_p.h"

#include "qscriptdebuggerbackend_p.h"
#include "qscriptdebuggercommand_p.h"
#include "qscriptdebuggerresponse_p.h"
#include "qscriptdebuggervalue_p.h"
#include "qscriptdebuggervalueproperty_p.h"
#include "qscriptbreakpointdata_p.h"
#include "qscriptobjectsnapshot_p.h"
#include "qscriptdebuggerobjectsnapshotdelta_p.h"

#include <QtCore/qstringlist.h>
#include <QtScript/qscriptengine.h>
#include <QtScript/qscriptcontextinfo.h>
#include <QtScript/qscriptvalueiterator.h>
#include <QtCore/qdebug.h>

Q_DECLARE_METATYPE(QScriptScriptsDelta)
Q_DECLARE_METATYPE(QScriptDebuggerValueProperty)
Q_DECLARE_METATYPE(QScriptDebuggerValuePropertyList)
Q_DECLARE_METATYPE(QScriptDebuggerObjectSnapshotDelta)

QT_BEGIN_NAMESPACE

/*!
  \since 4.5
  \class QScriptDebuggerCommandExecutor
  \internal

  \brief The QScriptDebuggerCommandExecutor applies debugger commands to a back-end.

  The execute() function takes a command (typically produced by a
  QScriptDebuggerFrontend) and applies it to a QScriptDebuggerBackend.

  \sa QScriptDebuggerCommmand
*/

class QScriptDebuggerCommandExecutorPrivate
{
public:
    QScriptDebuggerCommandExecutorPrivate();
    ~QScriptDebuggerCommandExecutorPrivate();
};

QScriptDebuggerCommandExecutorPrivate::QScriptDebuggerCommandExecutorPrivate()
{
}

QScriptDebuggerCommandExecutorPrivate::~QScriptDebuggerCommandExecutorPrivate()
{
}

QScriptDebuggerCommandExecutor::QScriptDebuggerCommandExecutor()
    : d_ptr(new QScriptDebuggerCommandExecutorPrivate())
{
}

QScriptDebuggerCommandExecutor::~QScriptDebuggerCommandExecutor()
{
}

static bool isPrefixOf(const QString &prefix, const QString &what)
{
    return ((what.length() > prefix.length())
            && what.startsWith(prefix));
}

/*!
  Applies the given \a command to the given \a backend.
*/
QScriptDebuggerResponse QScriptDebuggerCommandExecutor::execute(
    QScriptDebuggerBackend *backend,
    const QScriptDebuggerCommand &command)
{
    QScriptDebuggerResponse response;
    switch (command.type()) {
    case QScriptDebuggerCommand::None:
        break;

    case QScriptDebuggerCommand::Interrupt:
        backend->interruptEvaluation();
        break;

    case QScriptDebuggerCommand::Continue:
        if (backend->engine()->isEvaluating()) {
            backend->continueEvalution();
            response.setAsync(true);
        }
        break;

    case QScriptDebuggerCommand::StepInto: {
        QVariant attr = command.attribute(QScriptDebuggerCommand::StepCount);
        int count = attr.isValid() ? attr.toInt() : 1;
        backend->stepInto(count);
        response.setAsync(true);
    }   break;

    case QScriptDebuggerCommand::StepOver: {
        QVariant attr = command.attribute(QScriptDebuggerCommand::StepCount);
        int count = attr.isValid() ? attr.toInt() : 1;
        backend->stepOver(count);
        response.setAsync(true);
    }   break;

    case QScriptDebuggerCommand::StepOut:
        backend->stepOut();
        response.setAsync(true);
        break;

    case QScriptDebuggerCommand::RunToLocation:
        backend->runToLocation(command.fileName(), command.lineNumber());
        response.setAsync(true);
        break;

    case QScriptDebuggerCommand::RunToLocationByID:
        backend->runToLocation(command.scriptId(), command.lineNumber());
        response.setAsync(true);
        break;

    case QScriptDebuggerCommand::ForceReturn: {
        int contextIndex = command.contextIndex();
        QScriptDebuggerValue value = command.scriptValue();
        QScriptEngine *engine = backend->engine();
        QScriptValue realValue = value.toScriptValue(engine);
        backend->returnToCaller(contextIndex, realValue);
        response.setAsync(true);
    }   break;

    case QScriptDebuggerCommand::Resume:
        backend->resume();
        response.setAsync(true);
        break;

    case QScriptDebuggerCommand::SetBreakpoint: {
        QScriptBreakpointData data = command.breakpointData();
        if (!data.isValid())
            data = QScriptBreakpointData(command.fileName(), command.lineNumber());
        int id = backend->setBreakpoint(data);
        response.setResult(id);
    }   break;

    case QScriptDebuggerCommand::DeleteBreakpoint: {
        int id = command.breakpointId();
        if (!backend->deleteBreakpoint(id))
            response.setError(QScriptDebuggerResponse::InvalidBreakpointID);
    }   break;

    case QScriptDebuggerCommand::DeleteAllBreakpoints:
        backend->deleteAllBreakpoints();
        break;

    case QScriptDebuggerCommand::GetBreakpoints: {
        QScriptBreakpointMap bps = backend->breakpoints();
        if (!bps.isEmpty())
            response.setResult(bps);
    }   break;

    case QScriptDebuggerCommand::GetBreakpointData: {
        int id = command.breakpointId();
        QScriptBreakpointData data = backend->breakpointData(id);
        if (data.isValid())
            response.setResult(data);
        else
            response.setError(QScriptDebuggerResponse::InvalidBreakpointID);
    }   break;

    case QScriptDebuggerCommand::SetBreakpointData: {
        int id = command.breakpointId();
        QScriptBreakpointData data = command.breakpointData();
        if (!backend->setBreakpointData(id, data))
            response.setError(QScriptDebuggerResponse::InvalidBreakpointID);
    }   break;

    case QScriptDebuggerCommand::GetScripts: {
        QScriptScriptMap scripts = backend->scripts();
        if (!scripts.isEmpty())
            response.setResult(scripts);
    }   break;

    case QScriptDebuggerCommand::GetScriptData: {
        qint64 id = command.scriptId();
        QScriptScriptData data = backend->scriptData(id);
        if (data.isValid())
            response.setResult(data);
        else
            response.setError(QScriptDebuggerResponse::InvalidScriptID);
    }   break;

    case QScriptDebuggerCommand::ScriptsCheckpoint:
        backend->scriptsCheckpoint();
        response.setResult(qVariantFromValue(backend->scriptsDelta()));
        break;

    case QScriptDebuggerCommand::GetScriptsDelta:
        response.setResult(qVariantFromValue(backend->scriptsDelta()));
        break;

    case QScriptDebuggerCommand::ResolveScript:
        response.setResult(backend->resolveScript(command.fileName()));
        break;

    case QScriptDebuggerCommand::GetBacktrace:
        response.setResult(backend->backtrace());
        break;

    case QScriptDebuggerCommand::GetContextCount:
        response.setResult(backend->contextCount());
        break;

    case QScriptDebuggerCommand::GetContextState: {
        QScriptContext *ctx = backend->context(command.contextIndex());
        if (ctx)
            response.setResult(static_cast<int>(ctx->state()));
        else
            response.setError(QScriptDebuggerResponse::InvalidContextIndex);
    }   break;

    case QScriptDebuggerCommand::GetContextID: {
        int idx = command.contextIndex();
        if ((idx >= 0) && (idx < backend->contextCount()))
            response.setResult(backend->contextIds()[idx]);
        else
            response.setError(QScriptDebuggerResponse::InvalidContextIndex);
    }   break;

    case QScriptDebuggerCommand::GetContextInfo: {
        QScriptContext *ctx = backend->context(command.contextIndex());
        if (ctx)
            response.setResult(QScriptContextInfo(ctx));
        else
            response.setError(QScriptDebuggerResponse::InvalidContextIndex);
    }   break;

    case QScriptDebuggerCommand::GetThisObject: {
        QScriptContext *ctx = backend->context(command.contextIndex());
        if (ctx)
            response.setResult(ctx->thisObject());
        else
            response.setError(QScriptDebuggerResponse::InvalidContextIndex);
    }   break;

    case QScriptDebuggerCommand::GetActivationObject: {
        QScriptContext *ctx = backend->context(command.contextIndex());
        if (ctx)
            response.setResult(ctx->activationObject());
        else
            response.setError(QScriptDebuggerResponse::InvalidContextIndex);
    }   break;

    case QScriptDebuggerCommand::GetScopeChain: {
        QScriptContext *ctx = backend->context(command.contextIndex());
        if (ctx) {
            QScriptDebuggerValueList dest;
            QScriptValueList src = ctx->scopeChain();
            for (int i = 0; i < src.size(); ++i)
                dest.append(src.at(i));
            response.setResult(dest);
        } else {
            response.setError(QScriptDebuggerResponse::InvalidContextIndex);
        }
    }   break;

    case QScriptDebuggerCommand::ContextsCheckpoint: {
        response.setResult(qVariantFromValue(backend->contextsCheckpoint()));
    }   break;

    case QScriptDebuggerCommand::GetPropertyExpressionValue: {
        QScriptContext *ctx = backend->context(command.contextIndex());
        int lineNumber = command.lineNumber();
        QVariant attr = command.attribute(QScriptDebuggerCommand::UserAttribute);
        QStringList path = attr.toStringList();
        if (!ctx || path.isEmpty())
            break;
        QScriptContextInfo ctxInfo(ctx);
        if (ctx->callee().isValid()
            && ((lineNumber < ctxInfo.functionStartLineNumber())
                || (lineNumber > ctxInfo.functionEndLineNumber()))) {
            break;
        }
        QScriptValueList objects;
        int pathIndex = 0;
        if (path.at(0) == QLatin1String("this")) {
            objects.append(ctx->thisObject());
            ++pathIndex;
        } else {
            objects << ctx->scopeChain();
        }
        for (int i = 0; i < objects.size(); ++i) {
            QScriptValue val = objects.at(i);
            for (int j = pathIndex; val.isValid() && (j < path.size()); ++j) {
                val = val.property(path.at(j));
            }
            if (val.isValid()) {
                bool hadException = (ctx->state() == QScriptContext::ExceptionState);
                QString str = val.toString();
                if (!hadException && backend->engine()->hasUncaughtException())
                    backend->engine()->clearExceptions();
                response.setResult(str);
                break;
            }
        }
    }   break;

    case QScriptDebuggerCommand::GetCompletions: {
        QScriptContext *ctx = backend->context(command.contextIndex());
        QVariant attr = command.attribute(QScriptDebuggerCommand::UserAttribute);
        QStringList path = attr.toStringList();
        if (!ctx || path.isEmpty())
            break;
        QScriptValueList objects;
        QString prefix = path.last();
        QSet<QString> matches;
        if (path.size() > 1) {
            const QString &topLevelIdent = path.at(0);
            QScriptValue obj;
            if (topLevelIdent == QLatin1String("this")) {
                obj = ctx->thisObject();
            } else {
                QScriptValueList scopeChain;
                scopeChain = ctx->scopeChain();
                for (int i = 0; i < scopeChain.size(); ++i) {
                    QScriptValue oo = scopeChain.at(i).property(topLevelIdent);
                    if (oo.isObject()) {
                        obj = oo;
                        break;
                    }
                }
            }
            for (int i = 1; obj.isObject() && (i < path.size()-1); ++i)
                obj = obj.property(path.at(i));
            if (obj.isValid())
                objects.append(obj);
        } else {
            objects << ctx->scopeChain();
            QStringList keywords;
            keywords.append(QString::fromLatin1("this"));
            keywords.append(QString::fromLatin1("true"));
            keywords.append(QString::fromLatin1("false"));
            keywords.append(QString::fromLatin1("null"));
            for (int i = 0; i < keywords.size(); ++i) {
                const QString &kwd = keywords.at(i);
                if (isPrefixOf(prefix, kwd))
                    matches.insert(kwd);
            }
        }

        for (int i = 0; i < objects.size(); ++i) {
            QScriptValue obj = objects.at(i);
            while (obj.isObject()) {
                QScriptValueIterator it(obj);
                while (it.hasNext()) {
                    it.next();
                    QString propertyName = it.name();
                    if (isPrefixOf(prefix, propertyName))
                        matches.insert(propertyName);
                }
                obj = obj.prototype();
            }
        }
        QStringList matchesList = matches.toList();
        qStableSort(matchesList);
        response.setResult(matchesList);
    }   break;

    case QScriptDebuggerCommand::NewScriptObjectSnapshot: {
        int id = backend->newScriptObjectSnapshot();
        response.setResult(id);
    }   break;

    case QScriptDebuggerCommand::ScriptObjectSnapshotCapture: {
        int id = command.snapshotId();
        QScriptObjectSnapshot *snap = backend->scriptObjectSnapshot(id);
        Q_ASSERT(snap != 0);
        QScriptDebuggerValue object = command.scriptValue();
        Q_ASSERT(object.type() == QScriptDebuggerValue::ObjectValue);
        QScriptEngine *engine = backend->engine();
        QScriptValue realObject = object.toScriptValue(engine);
        Q_ASSERT(realObject.isObject());
        QScriptObjectSnapshot::Delta delta = snap->capture(realObject);
        QScriptDebuggerObjectSnapshotDelta result;
        result.removedProperties = delta.removedProperties;
        bool didIgnoreExceptions = backend->ignoreExceptions();
        backend->setIgnoreExceptions(true);
        for (int i = 0; i < delta.changedProperties.size(); ++i) {
            const QScriptValueProperty &src = delta.changedProperties.at(i);
            bool hadException = engine->hasUncaughtException();
            QString str = src.value().toString();
            if (!hadException && engine->hasUncaughtException())
                engine->clearExceptions();
            QScriptDebuggerValueProperty dest(src.name(), src.value(), str, src.flags());
            result.changedProperties.append(dest);
        }
        for (int j = 0; j < delta.addedProperties.size(); ++j) {
            const QScriptValueProperty &src = delta.addedProperties.at(j);
            bool hadException = engine->hasUncaughtException();
            QString str = src.value().toString();
            if (!hadException && engine->hasUncaughtException())
                engine->clearExceptions();
            QScriptDebuggerValueProperty dest(src.name(), src.value(), str, src.flags());
            result.addedProperties.append(dest);
        }
        backend->setIgnoreExceptions(didIgnoreExceptions);
        response.setResult(qVariantFromValue(result));
    }   break;

    case QScriptDebuggerCommand::DeleteScriptObjectSnapshot: {
        int id = command.snapshotId();
        backend->deleteScriptObjectSnapshot(id);
    }   break;

    case QScriptDebuggerCommand::NewScriptValueIterator: {
        QScriptDebuggerValue object = command.scriptValue();
        Q_ASSERT(object.type() == QScriptDebuggerValue::ObjectValue);
        QScriptEngine *engine = backend->engine();
        QScriptValue realObject = object.toScriptValue(engine);
        Q_ASSERT(realObject.isObject());
        int id = backend->newScriptValueIterator(realObject);
        response.setResult(id);
    }   break;

    case QScriptDebuggerCommand::GetPropertiesByIterator: {
        int id = command.iteratorId();
        int count = 1000;
        QScriptValueIterator *it = backend->scriptValueIterator(id);
        Q_ASSERT(it != 0);
        QScriptDebuggerValuePropertyList props;
        for (int i = 0; (i < count) && it->hasNext(); ++i) {
            it->next();
            QString name = it->name();
            QScriptValue value = it->value();
            QString valueAsString = value.toString();
            QScriptValue::PropertyFlags flags = it->flags();
            QScriptDebuggerValueProperty prp(name, value, valueAsString, flags);
            props.append(prp);
        }
        response.setResult(props);
    }   break;

    case QScriptDebuggerCommand::DeleteScriptValueIterator: {
        int id = command.iteratorId();
        backend->deleteScriptValueIterator(id);
    }   break;

    case QScriptDebuggerCommand::Evaluate: {
        int contextIndex = command.contextIndex();
        QString program = command.program();
        QString fileName = command.fileName();
        int lineNumber = command.lineNumber();
        backend->evaluate(contextIndex, program, fileName, lineNumber);
        response.setAsync(true);
    }   break;

    case QScriptDebuggerCommand::ScriptValueToString: {
        QScriptDebuggerValue value = command.scriptValue();
        QScriptEngine *engine = backend->engine();
        QScriptValue realValue = value.toScriptValue(engine);
        response.setResult(realValue.toString());
    }   break;

    case QScriptDebuggerCommand::SetScriptValueProperty: {
        QScriptDebuggerValue object = command.scriptValue();
        QScriptEngine *engine = backend->engine();
        QScriptValue realObject = object.toScriptValue(engine);
        QScriptDebuggerValue value = command.subordinateScriptValue();
        QScriptValue realValue = value.toScriptValue(engine);
        QString name = command.name();
        realObject.setProperty(name, realValue);
    }   break;

    case QScriptDebuggerCommand::ClearExceptions:
        backend->engine()->clearExceptions();
        break;

    case QScriptDebuggerCommand::UserCommand:
    case QScriptDebuggerCommand::MaxUserCommand:
        break;
    }
    return response;
}

QT_END_NAMESPACE
