/****************************************************************************
**
** 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 tools applications 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 <QDebug>
#include <QCoreApplication>
#include <QObject>
#include <QFile>
#include <QDir>
#include "trksignalhandler.h"
#include "trkutils.h"

class CrashState
{
public:
    uint pid;
    uint tid;
    QString crashReason;
    uint crashPC;
};

class TrkSignalHandlerPrivate
{
    friend class TrkSignalHandler;
public:
    TrkSignalHandlerPrivate();
    ~TrkSignalHandlerPrivate();
private:
    QTextStream out;
    QTextStream err;
    int loglevel;
    int lastpercent;
    QList<trk::Library> libraries;
    QFile crashlogtextfile;
    QFile crashstackfile;
    QList<CrashState> queuedCrashes;
    QList<int> dyingThreads;
    QString crashlogPath;
    bool crashlog;
    bool terminateNeeded;
};

void TrkSignalHandler::copyingStarted()
{
    if (d->loglevel > 0)
        d->out << "Copying..." << endl;
}

void TrkSignalHandler::canNotConnect(const QString &errorMessage)
{
    d->err << "Cannot connect - " << errorMessage << endl;
}

void TrkSignalHandler::canNotCreateFile(const QString &filename, const QString &errorMessage)
{
    d->err << "Cannot create file (" << filename << ") - " << errorMessage << endl;
}

void TrkSignalHandler::canNotWriteFile(const QString &filename, const QString &errorMessage)
{
    d->err << "Cannot write file (" << filename << ") - " << errorMessage << endl;
}

void TrkSignalHandler::canNotCloseFile(const QString &filename, const QString &errorMessage)
{
    d->err << "Cannot close file (" << filename << ") - " << errorMessage << endl;
}

void TrkSignalHandler::installingStarted()
{
    if (d->loglevel > 0)
        d->out << "Installing..." << endl;
}

void TrkSignalHandler::canNotInstall(const QString &packageFilename, const QString &errorMessage)
{
    d->err << "Cannot install file (" << packageFilename << ") - " << errorMessage << endl;
}

void TrkSignalHandler::installingFinished()
{
    if (d->loglevel > 0)
        d->out << "Installing finished" << endl;
}

void TrkSignalHandler::startingApplication()
{
    if (d->loglevel > 0)
        d->out << "Starting app..." << endl;
}

void TrkSignalHandler::applicationRunning(uint pid)
{
    Q_UNUSED(pid)
    if (d->loglevel > 0)
        d->out << "Running..." << endl;
}

void TrkSignalHandler::canNotRun(const QString &errorMessage)
{
    d->err << "Cannot run - " << errorMessage << endl;
}

void TrkSignalHandler::finished()
{
    if (d->loglevel > 0)
        d->out << "Done." << endl;
    QCoreApplication::quit();
}

void TrkSignalHandler::applicationOutputReceived(const QString &output)
{
    d->out << output << flush;
}

void TrkSignalHandler::copyProgress(int percent)
{
    if (d->loglevel > 0) {
        if (d->lastpercent == 0)
            d->out << "[                                                 ]\r[" << flush;
        while (percent > d->lastpercent) {
            d->out << QLatin1Char('#');
            d->lastpercent+=2; //because typical console is 80 chars wide
        }
        d->out.flush();
        if (percent==100)
            d->out << endl;
    }
}

void TrkSignalHandler::stateChanged(int state)
{
    if (d->loglevel > 1)
        d->out << "State" << state << endl;
}

void TrkSignalHandler::setLogLevel(int level)
{
    d->loglevel = level;
}

void TrkSignalHandler::setCrashLogging(bool enabled)
{
    d->crashlog = enabled;
}

void TrkSignalHandler::setCrashLogPath(QString path)
{
    d->crashlogPath = path;
}

bool lessThanCodeBase(const trk::Library& cs1, const trk::Library& cs2)
{
    return cs1.codeseg < cs2.codeseg;
}

void TrkSignalHandler::stopped(uint pc, uint pid, uint tid, const QString& reason)
{
    d->err << "STOPPED: pc=" << hex << pc << " pid=" << pid
           << " tid=" << tid << dec << " - " << reason << endl;

    if (d->crashlog) {
        CrashState cs;
        cs.pid = pid;
        cs.tid = tid;
        cs.crashPC = pc;
        cs.crashReason = reason;

        if (d->dyingThreads.contains(tid)) {
            if(d->queuedCrashes.isEmpty())
                emit terminate();
            else
                d->terminateNeeded = true;
        } else {
            d->queuedCrashes.append(cs);
            d->dyingThreads.append(tid);

            if (d->queuedCrashes.count() == 1) {
                d->err << "Fetching registers and stack..." << endl;
                emit getRegistersAndCallStack(pid, tid);
            }
        }
    }
    else
        emit terminate();
}

void TrkSignalHandler::registersAndCallStackReadComplete(const QList<uint>& registers, const QByteArray& stack)
{
    CrashState cs = d->queuedCrashes.first();
    QDir dir(d->crashlogPath);
    d->crashlogtextfile.setFileName(dir.filePath(QString("d_exc_%1.txt").arg(cs.tid)));
    d->crashstackfile.setFileName(dir.filePath(QString("d_exc_%1.stk").arg(cs.tid)));
    d->crashlogtextfile.open(QIODevice::WriteOnly);
    QTextStream crashlog(&d->crashlogtextfile);

    crashlog << "-----------------------------------------------------------------------------" << endl;
    crashlog << "EKA2 USER CRASH LOG" << endl;
    crashlog << "Thread Name: " << QString("ProcessID-%1::ThreadID-%2").arg(cs.pid).arg(cs.tid) << endl;
    crashlog << "Thread ID: " << cs.tid << endl;
    //this is wrong, but TRK doesn't make stack limit available so we lie
    crashlog << QString("User Stack %1-%2").arg(registers.at(13), 8, 16, QChar('0')).arg(registers.at(13) + stack.size(), 8, 16, QChar('0')) << endl;
    //this is also wrong, but TRK doesn't give all information for exceptions
    crashlog << QString("Panic: PC=%1 ").arg(cs.crashPC, 8, 16, QChar('0')) << cs.crashReason << endl;
    crashlog << endl;
    crashlog << "USER REGISTERS:" << endl;
    crashlog << QString("CPSR=%1").arg(registers.at(16), 8, 16, QChar('0')) << endl;
    for (int i=0;i<16;i+=4) {
        crashlog << QString("r%1=%2 %3 %4 %5")
            .arg(i, 2, 10, QChar('0'))
            .arg(registers.at(i), 8, 16, QChar('0'))
            .arg(registers.at(i+1), 8, 16, QChar('0'))
            .arg(registers.at(i+2), 8, 16, QChar('0'))
            .arg(registers.at(i+3), 8, 16, QChar('0')) << endl;
    }
    crashlog << endl;

    //emit info for post mortem debug
    qSort(d->libraries.begin(), d->libraries.end(), lessThanCodeBase);
    d->err << "Code Segments:" << endl;
    crashlog << "CODE SEGMENTS:" << endl;
    for(int i=0; i<d->libraries.count(); i++) {
        const trk::Library& seg = d->libraries.at(i);
        if(seg.pid != cs.pid)
            continue;
        if (d->loglevel > 1) {
            d->err << QString("Code: %1 Data: %2 Name: ")
                .arg(seg.codeseg, 8, 16, QChar('0'))
                .arg(seg.dataseg, 8, 16, QChar('0'))
                << seg.name << endl;
        }

        //produce fake code segment end addresses since we don't get the real ones from TRK
        uint end;
        if (i+1 < d->libraries.count())
            end = d->libraries.at(i+1).codeseg - 1;
        else
            end = 0xFFFFFFFF;

        crashlog << QString("%1-%2 ")
            .arg(seg.codeseg, 8, 16, QChar('0'))
            .arg(end, 8, 16, QChar('0'))
            << seg.name << endl;
    }

    d->crashlogtextfile.close();

    if (d->loglevel > 1) {
        d->err << "Registers:" << endl;
        for (int i=0;i<16;i++) {
            d->err << QString("R%1: %2 ").arg(i, 2, 10, QChar('0')).arg(registers.at(i), 8, 16, QChar('0'));
            if (i % 4 == 3)
                d->err << endl;
        }
        d->err << QString("CPSR: %1").arg(registers.at(16), 8, 16, QChar('0')) << endl;

        d->err << "Stack:" << endl;
        uint sp = registers.at(13);
        for(int i=0; i<stack.size(); i+=16, sp+=16) {
            d->err << QString("%1: ").arg(sp, 8, 16, QChar('0'));
            d->err << trk::stringFromArray(stack.mid(i,16));
            d->err << endl;
        }
    }
    d->crashstackfile.open(QIODevice::WriteOnly);
    d->crashstackfile.write(stack);
    d->crashstackfile.close();

    if (d->loglevel > 0)
        d->err << "Crash logs saved to " << d->crashlogtextfile.fileName() << " & " << d->crashstackfile.fileName() << endl;

    // resume the thread to allow Symbian OS to handle the panic normally.
    // terminate when a non main thread is suspended reboots the phone (TRK bug)
    emit resume(cs.pid, cs.tid);

    //fetch next crashed thread
    d->queuedCrashes.removeFirst();
    if (d->queuedCrashes.count()) {
        cs = d->queuedCrashes.first();
        d->err << "Fetching registers and stack..." << endl;
        emit getRegistersAndCallStack(cs.pid, cs.tid);
    }
    else if (d->terminateNeeded)
        emit terminate();

}

void TrkSignalHandler::libraryLoaded(const trk::Library &lib)
{
    d->libraries << lib;
}

void TrkSignalHandler::libraryUnloaded(const trk::Library &lib)
{
    for (QList<trk::Library>::iterator i = d->libraries.begin(); i != d->libraries.end(); i++) {
        if((*i).name == lib.name && (*i).pid == lib.pid)
            i = d->libraries.erase(i);
    }
}

void TrkSignalHandler::timeout()
{
    d->err << "FAILED: stopping test due to timeout" << endl;
    emit terminate();
}

TrkSignalHandlerPrivate::TrkSignalHandlerPrivate()
    : out(stdout),
    err(stderr),
    loglevel(0),
    lastpercent(0),
    terminateNeeded(false)
{

}

TrkSignalHandlerPrivate::~TrkSignalHandlerPrivate()
{
    out.flush();
    err.flush();
}

TrkSignalHandler::TrkSignalHandler()
    : d(new TrkSignalHandlerPrivate())
{
}

TrkSignalHandler::~TrkSignalHandler()
{
    delete d;
}
