
/*---------------------------------------------------------------------------*/
/* debug_readlog.cpp                                                         */
/* copyright (c) innovaphone 2012                                            */
/*                                                                           */
/*---------------------------------------------------------------------------*/

#define DEBUG_READLOG_CPP_

#include "platform/platform.h"

#include "common/os/iomux.h"
#include "common/interface/task.h"
#include "common/interface/stask.h"
#include "common/lib/tasks_file.h"

#include "debug_readlog.h"

#define FILE_ "debug_readlog.cpp"

USING_NAMESPACE

/*---------------------------------------------------------------------------*/

DebugTaskFileRead::DebugTaskFileRead(class STaskContext * context, const char * workingPath, const char * fileName, unsigned length, bool last) :
    TaskFileRead(context, workingPath, fileName, length, last)
{
    progress_pending = false;
}

DebugTaskFileRead::~DebugTaskFileRead()
{
}

/*---------------------------------------------------------------------------*/

class IDebugReadLog * IDebugReadLog::Create(class UDebugReadLog * debugReadLogUser, class STaskContext * context, unsigned length, bool last, bool continuous)
{
    return new DebugReadLog(debugReadLogUser, context, length, last, continuous);
}

DebugReadLog::DebugReadLog(class UDebugReadLog * debugReadLogUser, class STaskContext * context, unsigned length, bool last, bool continuous)
{
    this->debugReadLogUser = debugReadLogUser;
    readContext = context;
    readLength = length;
    readLast = last;
    readContinuous = continuous;
    readCount = 0;
    readAllocated = 16;
    readList = (DebugTaskFileRead **)(malloc(readAllocated * sizeof(DebugTaskFileRead *)));
    user = NULL;
}

DebugReadLog::~DebugReadLog()
{
    free(readList);
}

void DebugReadLog::TaskComplete(class ITask * const task)
{
    unsigned i;

    i = 0;
    while (readList[i] != task) {
        i++;
    }
    delete readList[i];
    readCount--;
    while (i < readCount) {
        readList[i] = readList[i+1];
        i++;
    }
    if (readCount == 0) {
        user->TaskComplete(this);
    }
    else {
        DebugTaskFileRead *read = readList[0];
        if (read->progress_pending) {
            read->progress_pending = false;
            if ((read->getLength() == 0) || (readLength == 0) || readLast) {
                read->read(0, true);
            }
            else {
                user->TaskProgress(this, 0);
            }
        }
    }
}

void DebugReadLog::TaskFailed(class ITask * const task)
{
    unsigned i;

    i = 0;
    while (readList[i] != task) {
        i++;
    }
    delete readList[i];
    readCount--;
    while (i < readCount) {
        readList[i] = readList[i+1];
        i++;
    }
    if (readCount == 0) {
        user->TaskComplete(this);
    }
    else {
        DebugTaskFileRead *read = readList[0];
        if (read->progress_pending) {
            read->progress_pending = false;
            if ((read->getLength() == 0) || (readLength == 0) || readLast) {
                read->read(0, true);
            }
            else {
                user->TaskProgress(this, 0);
            }
        }
    }
}

void DebugReadLog::TaskProgress(class ITask * const task, dword progress)
{
    unsigned i;

    DebugTaskFileRead *read = readList[0];
    if (read == task) {
        if ((read->getLength() == 0) || (readLength == 0) || readLast) {
            read->read(0, true);
        }
        else {
            user->TaskProgress(this, 0);
        }
    }
    else {
        i = 1;
        while (readList[i] != task) {
            i++;
        }
        read = readList[i];
        read->progress_pending = true;
    }
}

void DebugReadLog::Add(const char * workingPath, const char * fileName)
{
    DebugTaskFileRead ** p;

    if (readCount == readAllocated) {
        readAllocated *= 2;
        p = (DebugTaskFileRead **)(malloc(readAllocated * sizeof(DebugTaskFileRead *)));
        memcpy(p, readList, readCount * sizeof(DebugTaskFileRead *));
        free(readList);
        readList = p;
    }
    readList[readCount++] = new DebugTaskFileRead(readContext, workingPath, fileName, readLength, readLast);
}

void DebugReadLog::Start(class UTask * user)
{
    unsigned i;

    this->user = user;
    debugReadLogUser->DebugReadLogAddFiles(this);
    for (i = 0; i < readCount; i++) {
        DebugTaskFileRead *read = readList[i];
        read->Start(this);
    }
}

void DebugReadLog::read(unsigned length, bool last)
{
    readLength = length;
    readLast = last;
    readList[0]->read(length, last);
}

unsigned DebugReadLog::getLength()
{
    return (readList[0]->getLength());
}

void DebugReadLog::getData(byte * buffer, unsigned length)
{
    readList[0]->getData(buffer, length);
}

/*----------------------------------------------------------------------------*/
