/****************************************************************************
**
** Copyright (C) 2017 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** BSD License Usage
** Alternatively, you may use this file under the terms of the BSD license
** as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
**   * Redistributions of source code must retain the above copyright
**     notice, this list of conditions and the following disclaimer.
**   * 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.
**   * Neither the name of The Qt Company Ltd nor the names of its
**     contributors may be used to endorse or promote products derived
**     from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
** OWNER 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."
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "scriptdebugger.h"
#include "scriptbreakpointmanager.h"

#include <QtScript/QScriptEngine>
#include <QtScript/QScriptEngineAgent>
#include <QtScript/QScriptContextInfo>
#include <QtScript/QScriptValueIterator>
#include <QtCore/QTextStream>
#include <QtCore/QStack>

static QString safeValueToString(const QScriptValue &value)
{
    if (value.isObject())
        return QLatin1String("[object Object]");
    else
        return value.toString();
}

class ScriptInfo;
class ScriptBreakpointManager;

class ScriptDebuggerPrivate
    : public QScriptEngineAgent
{
    Q_DECLARE_PUBLIC(ScriptDebugger)
public:
    enum Mode {
        Run,
        StepInto,
        StepOver
    };

    ScriptDebuggerPrivate(QScriptEngine *engine);
    ~ScriptDebuggerPrivate();

    // QScriptEngineAgent interface
    void scriptLoad(qint64 id, const QString &program,
                    const QString &fileName, int lineNumber);
    void scriptUnload(qint64 id);

    void positionChange(qint64 scriptId,
                        int lineNumber, int columnNumber);

    void functionEntry(qint64 scriptId);
    void functionExit(qint64 scriptId,
                      const QScriptValue &returnValue);

    void exceptionThrow(qint64 scriptId,
                        const QScriptValue &exception, bool hasHandler);


    void interactive();
    bool executeCommand(const QString &command, const QStringList &args);

    void setMode(Mode mode);
    Mode mode() const;

    int frameCount() const;
    void setCurrentFrameIndex(int index);
    int currentFrameIndex() const;

    QScriptContext *frameContext(int index) const;
    QScriptContext *currentFrameContext() const;

    ScriptInfo *scriptInfo(QScriptContext *context) const;

    int listLineNumber() const;
    void setListLineNumber(int lineNumber);

    QString readLine();
    void output(const QString &text);
    void message(const QString &text);
    void errorMessage(const QString &text);

    // attributes
    QTextStream *m_defaultInputStream;
    QTextStream *m_defaultOutputStream;
    QTextStream *m_defaultErrorStream;
    QTextStream *m_inputStream;
    QTextStream *m_outputStream;
    QTextStream *m_errorStream;

    ScriptBreakpointManager *m_bpManager;
    Mode m_mode;
    QMap<qint64, ScriptInfo*> m_scripts;
    QMap<QScriptContext*, QStack<qint64> > m_contextProgramIds;

    QString m_lastInteractiveCommand;
    QString m_commandPrefix;
    int m_stepDepth;
    int m_currentFrameIndex;
    int m_listLineNumber;

    ScriptDebugger *q_ptr;
};

class ScriptInfo
{
public:
    ScriptInfo(const QString &code, const QString &fileName, int lineNumber)
        : m_code(code), m_fileName(fileName), m_lineNumber(lineNumber)
        { }

    inline QString code() const
        { return m_code; }
    inline QString fileName() const
        { return m_fileName; }
    inline int lineNumber() const
        { return m_lineNumber; }

    QString lineText(int lineNumber);
    QMap<int, int> m_lineOffsets;

private:
    int lineOffset(int lineNumber);

    QString m_code;
    QString m_fileName;
    int m_lineNumber;
};

int ScriptInfo::lineOffset(int lineNumber)
{
    QMap<int, int>::const_iterator it = m_lineOffsets.constFind(lineNumber);
    if (it != m_lineOffsets.constEnd())
        return it.value();

    int offset;
    it = m_lineOffsets.constFind(lineNumber - 1);
    if (it != m_lineOffsets.constEnd()) {
        offset = it.value();
        offset = m_code.indexOf(QLatin1Char('\n'), offset);
        if (offset != -1)
            ++offset;
        m_lineOffsets.insert(lineNumber, offset);
    } else {
        int index;
        it = m_lineOffsets.lowerBound(lineNumber);
        if (it != m_lineOffsets.constBegin())
            --it;
        if (it != m_lineOffsets.constBegin()) {
            index = it.key();
            offset = it.value();
        } else {
            index = m_lineNumber;
            offset = 0;
        }
        int j = index;
        for ( ; j < lineNumber; ++j) {
            m_lineOffsets.insert(j, offset);
            offset = m_code.indexOf(QLatin1Char('\n'), offset);
            if (offset == -1)
                break;
            ++offset;
        }
        m_lineOffsets.insert(j, offset);
    }
    return offset;
}

QString ScriptInfo::lineText(int lineNumber)
{
    int startOffset = lineOffset(lineNumber);
    if (startOffset == -1)
        return QString();
    int endOffset = lineOffset(lineNumber + 1);
    if (endOffset == -1)
        return m_code.mid(startOffset);
    else
        return m_code.mid(startOffset, endOffset - startOffset - 1);
}



ScriptDebuggerPrivate::ScriptDebuggerPrivate(QScriptEngine *engine)
    : QScriptEngineAgent(engine), m_mode(Run)
{
    m_commandPrefix = QLatin1String(".");
    m_bpManager = new ScriptBreakpointManager;
    m_defaultInputStream = new QTextStream(stdin);
    m_defaultOutputStream = new QTextStream(stdout);
    m_defaultErrorStream = new QTextStream(stderr);
    m_inputStream = m_defaultInputStream;
    m_outputStream = m_defaultOutputStream;
    m_errorStream = m_defaultErrorStream;
}

ScriptDebuggerPrivate::~ScriptDebuggerPrivate()
{
    delete m_defaultInputStream;
    delete m_defaultOutputStream;
    delete m_defaultErrorStream;
    delete m_bpManager;
    qDeleteAll(m_scripts);
}

QString ScriptDebuggerPrivate::readLine()
{
    return m_inputStream->readLine();
}

void ScriptDebuggerPrivate::output(const QString &text)
{
    *m_outputStream << text;
}

void ScriptDebuggerPrivate::message(const QString &text)
{
    *m_outputStream << text << endl;
    m_outputStream->flush();
}

void ScriptDebuggerPrivate::errorMessage(const QString &text)
{
    *m_errorStream << text << endl;
    m_errorStream->flush();
}

void ScriptDebuggerPrivate::setMode(Mode mode)
{
    m_mode = mode;
}

ScriptDebuggerPrivate::Mode ScriptDebuggerPrivate::mode() const
{
    return m_mode;
}

QScriptContext *ScriptDebuggerPrivate::frameContext(int index) const
{
    QScriptContext *ctx = engine()->currentContext();
    for (int i = 0; i < index; ++i) {
        ctx = ctx->parentContext();
        if (!ctx)
            break;
    }
    return ctx;
}

int ScriptDebuggerPrivate::currentFrameIndex() const
{
    return m_currentFrameIndex;
}

void ScriptDebuggerPrivate::setCurrentFrameIndex(int index)
{
    m_currentFrameIndex = index;
    m_listLineNumber = -1;
}

int ScriptDebuggerPrivate::listLineNumber() const
{
    return m_listLineNumber;
}

void ScriptDebuggerPrivate::setListLineNumber(int lineNumber)
{
    m_listLineNumber = lineNumber;
}

QScriptContext *ScriptDebuggerPrivate::currentFrameContext() const
{
    return frameContext(currentFrameIndex());
}

int ScriptDebuggerPrivate::frameCount() const
{
    int count = 0;
    QScriptContext *ctx = engine()->currentContext();
    while (ctx) {
        ++count;
        ctx = ctx->parentContext();
    }
    return count;
}

ScriptInfo *ScriptDebuggerPrivate::scriptInfo(QScriptContext *context) const
{
    QStack<qint64> pids = m_contextProgramIds.value(context);
    if (pids.isEmpty())
        return 0;
    return m_scripts.value(pids.top());
}

void ScriptDebuggerPrivate::interactive()
{
    setCurrentFrameIndex(0);

    QString qsdbgPrompt = QString::fromLatin1("(qsdbg) ");
    QString dotPrompt = QString::fromLatin1(".... ");
    QString prompt = qsdbgPrompt;

    QString code;

    forever {

         *m_outputStream << prompt;
        m_outputStream->flush();

        QString line = readLine();

        if (code.isEmpty() && (line.isEmpty() || line.startsWith(m_commandPrefix))) {
            if (line.isEmpty())
                line = m_lastInteractiveCommand;
            else
                m_lastInteractiveCommand = line;

            QStringList parts = line.split(QLatin1Char(' '), QString::SkipEmptyParts);
            if (!parts.isEmpty()) {
                QString command = parts.takeFirst().mid(1);
                if (executeCommand(command, parts))
                    break;
            }

        } else {
            if (line.isEmpty())
                continue;

            code += line;
            code += QLatin1Char('\n');

            if (line.trimmed().isEmpty()) {
                continue;

            } else if (! engine()->canEvaluate(code)) {
                prompt = dotPrompt;

            } else {
                setMode(Run);
                QScriptValue result = engine()->evaluate(code, QLatin1String("typein"));

                code.clear();
                prompt = qsdbgPrompt;

                if (! result.isUndefined()) {
                    errorMessage(result.toString());
                    engine()->clearExceptions();
                }
            }
        }
    }
}

bool ScriptDebuggerPrivate::executeCommand(const QString &command, const QStringList &args)
{
    if (command == QLatin1String("c")
        || command == QLatin1String("continue")) {
        setMode(Run);
        return true;
    } else if (command == QLatin1String("s")
               || command == QLatin1String("step")) {
        setMode(StepInto);
        return true;
    } else if (command == QLatin1String("n")
               || command == QLatin1String("next")) {
        setMode(StepOver);
        m_stepDepth = 0;
        return true;
    } else if (command == QLatin1String("f")
               || command == QLatin1String("frame")) {
        bool ok = false;
        int index = args.value(0).toInt(&ok);
        if (ok) {
            if (index < 0 || index >= frameCount()) {
                errorMessage("No such frame.");
            } else {
                setCurrentFrameIndex(index);
                QScriptContext *ctx = currentFrameContext();
                message(QString::fromLatin1("#%0  %1").arg(index).arg(ctx->toString()));
            }
        }
    } else if (command == QLatin1String("bt")
               || command == QLatin1String("backtrace")) {
        QScriptContext *ctx = engine()->currentContext();
        int index = -1;
        while (ctx) {
            ++index;
            QString line = ctx->toString();
            message(QString::fromLatin1("#%0  %1").arg(index).arg(line));
            ctx = ctx->parentContext();
        }
    } else if (command == QLatin1String("up")) {
        int index = currentFrameIndex() + 1;
        if (index == frameCount()) {
            errorMessage(QString::fromLatin1("Initial frame selected; you cannot go up."));
        } else {
            setCurrentFrameIndex(index);
            QScriptContext *ctx = currentFrameContext();
            message(QString::fromLatin1("#%0  %1").arg(index).arg(ctx->toString()));
        }
    } else if (command == QLatin1String("down")) {
        int index = currentFrameIndex() - 1;
        if (index < 0) {
            errorMessage(QString::fromLatin1("Bottom (innermost) frame selected; you cannot go down."));
        } else {
            setCurrentFrameIndex(index);
            QScriptContext *ctx = currentFrameContext();
            message(QString::fromLatin1("#%0  %1").arg(index).arg(ctx->toString()));
        }
    } else if (command == QLatin1String("b")
               || command == QLatin1String("break")) {
        QString str = args.value(0);
        int colonIndex = str.indexOf(QLatin1Char(':'));
        if (colonIndex != -1) {
            // filename:line form
            QString fileName = str.left(colonIndex);
            int lineNumber = str.mid(colonIndex+1).toInt();
            int id = m_bpManager->setBreakpoint(fileName, lineNumber);
            message(QString::fromLatin1("Breakpoint %0 at %1, line %2.").arg(id+1).arg(fileName).arg(lineNumber));
        } else {
            // function
            QScriptValue fun = engine()->globalObject().property(str);
            if (fun.isFunction()) {
                int id = m_bpManager->setBreakpoint(fun);
                message(QString::fromLatin1("Breakpoint %0 at %1().").arg(id+1).arg(str));
            }
        }
    } else if (command == QLatin1String("d")
               || command == QLatin1String("delete")) {
        int id = args.value(0).toInt() - 1;
        m_bpManager->removeBreakpoint(id);
    } else if (command == QLatin1String("disable")) {
        int id = args.value(0).toInt() - 1;
        m_bpManager->setBreakpointEnabled(id, false);
    } else if (command == QLatin1String("enable")) {
        int id = args.value(0).toInt() - 1;
        m_bpManager->setBreakpointEnabled(id, true);
    } else if (command == QLatin1String("list")) {
        QScriptContext *ctx = currentFrameContext();
        ScriptInfo *progInfo = scriptInfo(ctx);
        if (!progInfo) {
            errorMessage("No source text available for this frame.");
        } else {
            QScriptContextInfo ctxInfo(ctx);
            bool ok;
            int line = args.value(0).toInt(&ok);
            if (ok) {
                line = qMax(1, line - 5);
            } else {
                line = listLineNumber();
                if (line == -1)
                    line = qMax(progInfo->lineNumber(), ctxInfo.lineNumber() - 5);
            }
            for (int i = line; i < line + 10; ++i) {
                message(QString::fromLatin1("%0\t%1").arg(i).arg(progInfo->lineText(i)));
            }
            setListLineNumber(line + 10);
        }
    } else if (command == QLatin1String("info")) {
        if (args.size() < 1) {
        } else {
            QString what = args.value(0);
            if (what == QLatin1String("locals")) {
                QScriptValueIterator it(currentFrameContext()->activationObject());
                while (it.hasNext()) {
                    it.next();
                    QString line;
                    line.append(it.name());
                    line.append(QLatin1String(" = "));
                    line.append(safeValueToString(it.value()));
                    message(line);
                }
            }
        }
    } else if (command == QLatin1String("help")) {
        message("continue - continue execution\n"
                "step     - step into statement\n"
                "next     - step over statement\n"
                "list     - show where you are\n"
                "\n"
                "break    - set breakpoint\n"
                "delete   - remove breakpoint\n"
                "disable  - disable breakpoint\n"
                "enable   - enable breakpoint\n"
                "\n"
                "backtrace - show backtrace\n"
                "up       - one frame up\n"
                "down     - one frame down\n"
                "frame    - set frame\n"
                "\n"
                "info locals - show local variables");
    } else {
        errorMessage(QString::fromLatin1("Undefined command \"%0\". Try \"help\".")
                     .arg(command));
    }

    return false;
}


// QScriptEngineAgent interface

void ScriptDebuggerPrivate::scriptLoad(qint64 id, const QString &program,
                                       const QString &fileName, int lineNumber)
{
    ScriptInfo *info = new ScriptInfo(program, fileName, lineNumber);
    m_scripts.insert(id, info);
}

void ScriptDebuggerPrivate::scriptUnload(qint64 id)
{
    ScriptInfo *info = m_scripts.take(id);
    delete info;
}

void ScriptDebuggerPrivate::functionEntry(qint64 scriptId)
{
    if (scriptId != -1) {
        QScriptContext *ctx = engine()->currentContext();
        QStack<qint64> ids = m_contextProgramIds.value(ctx);
        ids.push(scriptId);
        m_contextProgramIds.insert(ctx, ids);
    }

    if (mode() == StepOver)
        ++m_stepDepth;
}

void ScriptDebuggerPrivate::functionExit(qint64 scriptId,
                                         const QScriptValue &/*returnValue*/)
{
    if (scriptId != -1) {
        QScriptContext *ctx = engine()->currentContext();
        QStack<qint64> ids = m_contextProgramIds.value(ctx);
        Q_ASSERT(!ids.isEmpty());
        Q_ASSERT(ids.top() == scriptId);
        ids.pop();
        m_contextProgramIds.insert(ctx, ids);
    }

    if (mode() == StepOver)
        --m_stepDepth;
}

void ScriptDebuggerPrivate::positionChange(qint64 scriptId,
                                           int lineNumber, int /*columnNumber*/)
{
    ScriptInfo *info = 0;
    bool enterInteractiveMode = false;

    if (m_bpManager->hasBreakpoints()) {
        // check if we hit a breakpoint
        info = m_scripts.value(scriptId);
        QScriptContext *ctx = engine()->currentContext();
        QScriptContextInfo ctxInfo(ctx);
        QScriptValue callee = ctx->callee();

        // try fileName:lineNumber
        int bpid = m_bpManager->findBreakpoint(info->fileName(), lineNumber);
        if ((bpid != -1) && m_bpManager->isBreakpointEnabled(bpid)) {
            message(QString::fromLatin1("Breakpoint %0 at %1:%2")
                    .arg(bpid + 1).arg(info->fileName()).arg(lineNumber));
            if (m_bpManager->isBreakpointSingleShot(bpid))
                m_bpManager->removeBreakpoint(bpid);
        }
        if (bpid == -1) {
            // try function
            bpid = m_bpManager->findBreakpoint(callee);
            if ((bpid != -1) && m_bpManager->isBreakpointEnabled(bpid)) {
                message(QString::fromLatin1("Breakpoint %0, %1()")
                        .arg(bpid + 1).arg(ctxInfo.functionName()));
                if (m_bpManager->isBreakpointSingleShot(bpid))
                    m_bpManager->removeBreakpoint(bpid);
            }
        }
        if ((bpid == -1) && !ctxInfo.functionName().isEmpty()) {
            // try functionName:fileName
            bpid = m_bpManager->findBreakpoint(ctxInfo.functionName(), ctxInfo.fileName());
            if ((bpid != -1) && m_bpManager->isBreakpointEnabled(bpid)) {
                message(QString::fromLatin1("Breakpoint %0, %1():%2").arg(bpid + 1)
                        .arg(ctxInfo.functionName()).arg(ctxInfo.fileName()));
                if (m_bpManager->isBreakpointSingleShot(bpid))
                    m_bpManager->removeBreakpoint(bpid);
            }
        }

        enterInteractiveMode = (bpid != -1);
    }

    switch (mode()) {
    case Run:
        break;

    case StepInto:
        enterInteractiveMode = true;
        break;

    case StepOver:
        enterInteractiveMode = enterInteractiveMode || (m_stepDepth <= 0);
        break;
    }

    if (enterInteractiveMode) {
        if (!info)
            info = m_scripts.value(scriptId);
        Q_ASSERT(info);        
        message(QString::fromLatin1("%0\t%1").arg(lineNumber).arg(info->lineText(lineNumber)));
        interactive();
    }
}

void ScriptDebuggerPrivate::exceptionThrow(qint64 /*scriptId*/,
                                           const QScriptValue &exception,
                                           bool hasHandler)
{
    if (!hasHandler) {
        errorMessage(QString::fromLatin1("uncaught exception: %0").arg(exception.toString()));
        QScriptContext *ctx = engine()->currentContext();
        int lineNumber = QScriptContextInfo(ctx).lineNumber();
        ScriptInfo *info = scriptInfo(ctx);
        QString lineText = info ? info->lineText(lineNumber) : QString("(no source text available)");
        message(QString::fromLatin1("%0\t%1").arg(lineNumber).arg(lineText));
        interactive();
    }
}



ScriptDebugger::ScriptDebugger(QScriptEngine *engine)
    : d_ptr(new ScriptDebuggerPrivate(engine))
{
    d_ptr->q_ptr = this;
    engine->setAgent(d_ptr);
}

ScriptDebugger::ScriptDebugger(QScriptEngine *engine, ScriptDebuggerPrivate &dd)
    : d_ptr(&dd)
{
    d_ptr->q_ptr = this;
    engine->setAgent(d_ptr);
}

ScriptDebugger::~ScriptDebugger()
{
    delete d_ptr;
    d_ptr = 0;
}

void ScriptDebugger::breakAtNextStatement()
{
    Q_D(ScriptDebugger);
    d->setMode(ScriptDebuggerPrivate::StepInto);
}

void ScriptDebugger::setBreakpoint(const QString &fileName, int lineNumber)
{
    Q_D(ScriptDebugger);
    d->m_bpManager->setBreakpoint(fileName, lineNumber);
}

void ScriptDebugger::setBreakpoint(const QString &functionName, const QString &fileName)
{
    Q_D(ScriptDebugger);
    d->m_bpManager->setBreakpoint(functionName, fileName);
}

void ScriptDebugger::setBreakpoint(const QScriptValue &function)
{
    Q_D(ScriptDebugger);
    d->m_bpManager->setBreakpoint(function);
}

QTextStream *ScriptDebugger::inputStream() const
{
    Q_D(const ScriptDebugger);
    return d->m_inputStream;
}

void ScriptDebugger::setInputStream(QTextStream *inputStream)
{
    Q_D(ScriptDebugger);
    d->m_inputStream = inputStream;
}

QTextStream *ScriptDebugger::outputStream() const
{
    Q_D(const ScriptDebugger);
    return d->m_outputStream;
}

void ScriptDebugger::setOutputStream(QTextStream *outputStream)
{
    Q_D(ScriptDebugger);
    d->m_outputStream = outputStream;
}

QTextStream *ScriptDebugger::errorStream() const
{
    Q_D(const ScriptDebugger);
    return d->m_errorStream;
}

void ScriptDebugger::setErrorStream(QTextStream *errorStream)
{
    Q_D(ScriptDebugger);
    d->m_errorStream = errorStream;
}
