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

#define DEBUG_LOGFLAGS_CPP_

#include "platform/platform.h"

#include "common/os/iomux.h"
#include "common/interface/socket.h"
#include "common/lib/appservice.h"
#include "debug_logflags.h"

#define FILE_ "debug_logflags.cpp"

USING_NAMESPACE

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

DebugLogInstance::DebugLogInstance(const char * appName, const char * appDomain, class IInstanceLog * instanceLog, class AppService * appService)
{
    this->appName = _strdup(appName);
    this->appDomain = _strdup(appDomain);
    this->instanceLog = instanceLog;
    this->appService = appService;
}

DebugLogInstance::~DebugLogInstance()
{
    if (appName) free(appName);
    if (appDomain) free(appDomain);
}

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

DebugLogFlags::DebugLogFlags()
{
    commonLogFlags = 0;
    noHexdump = false;
    logInstanceCount = 0;
    logInstanceAllocated = 16;
    logInstances = (class DebugLogInstance **)(malloc(logInstanceAllocated * sizeof(class DebugLogInstance *)));
    logFlagsUserCount = 0;
    logFlagsUserAllocated = 16;
    logFlagsUsers = (class UDebugLogFlags **)(malloc(logFlagsUserAllocated * sizeof(class UDebugLogFlags *)));
    getLogActive = false;
}

DebugLogFlags::~DebugLogFlags()
{
    unsigned i;

    for (i = 0; i < logInstanceCount; i++) {
        delete logInstances[i];
    }
    free(logInstances);
    free(logFlagsUsers);
}

void DebugLogFlags::AddUser(UDebugLogFlags * logFlagsUser)
{
    class UDebugLogFlags ** p;

    if (logFlagsUserCount == logFlagsUserAllocated) {
        logFlagsUserAllocated *= 2;
        p = (class UDebugLogFlags **)(malloc(logFlagsUserAllocated * sizeof(class UDebugLogFlags *)));
        memcpy(p, logFlagsUsers, logFlagsUserCount * sizeof(class UDebugLogFlags *));
        free(logFlagsUsers);
        logFlagsUsers = p;
    }
    logFlagsUsers[logFlagsUserCount++] = logFlagsUser;
    logFlagsUser->DebugLogFlagsChanged(this, NULL, NULL, commonLogFlags, noHexdump, logFlagsUser);
}

void DebugLogFlags::RemoveUser(UDebugLogFlags * logFlagsUser)
{
    unsigned i;

    i = 0;
    while (logFlagsUsers[i] != logFlagsUser) {
        i++;
    }
    logFlagsUserCount--;
    while (i < logFlagsUserCount) {
        logFlagsUsers[i] = logFlagsUsers[i+1];
        i++;
    }
}

void DebugLogFlags::Add(const char * appName, const char * appDomain, class IInstanceLog * instanceLog, class AppService * appService)
{
    class DebugLogInstance ** p;

    if (logInstanceCount == logInstanceAllocated) {
        logInstanceAllocated *= 2;
        p = (class DebugLogInstance **)(malloc(logInstanceAllocated * sizeof(class DebugLogInstance *)));
        memcpy(p, logInstances, logInstanceCount * sizeof(class DebugLogInstance *));
        free(logInstances);
        logInstances = p;
    }
    logInstances[logInstanceCount++] = new DebugLogInstance(appName, appDomain, instanceLog, appService);
    if (appService) {
        appService->SetAllInstancesLogFlags(commonLogFlags);
    }
    else {
        instanceLog->SetLogFlags(commonLogFlags);
    }
}

void DebugLogFlags::Set(const char * appName, const char * appDomain, ulong64 flags, bool noHexdump, UDebugLogFlags * src)
{
    unsigned i;

    if (!appName && !appDomain) {
        commonLogFlags = flags;
        this->noHexdump = noHexdump;
    }
    for (i = 0; i < logInstanceCount; i++) {
        if ((!appName || (strcmp(appName ? appName : "", logInstances[i]->appName ? logInstances[i]->appName : "") == 0))
         && (!appDomain || (strcmp(appDomain ? appDomain : "", logInstances[i]->appDomain ? logInstances[i]->appDomain : "") == 0))) {
            if (logInstances[i]->appService) {
                logInstances[i]->appService->SetAllInstancesLogFlags(flags);
            }
            else {
                logInstances[i]->instanceLog->SetLogFlags(getLogActive ? 0 : flags);
            }
        }
    }
    debug->SetLogFlags(flags);
    debug->SetHexdump(!noHexdump);
    for (i = 0; i < logFlagsUserCount; i++) {
        logFlagsUsers[i]->DebugLogFlagsChanged(this, appName, appDomain, flags, noHexdump, src);
    }
}

void DebugLogFlags::GetLogActive(bool active)
{
    unsigned i;

    if (active ^ getLogActive) {
        getLogActive = active;
        for (i = 0; i < logInstanceCount; i++) {
            if (!logInstances[i]->appService) {
                logInstances[i]->instanceLog->SetLogFlags(getLogActive ? 0 : commonLogFlags);
            }
        }
    }
}

bool DebugLogFlags::Enabled()
{
    unsigned i;
    bool enabled;

    enabled = false;
    for (i = 0; i < logInstanceCount; i++) {
        if (logInstances[i]->instanceLog->LogFlagSet((enum LogFlags)(0xffffffffffffffffULL))) {
            enabled = true;
        }
    }
    return enabled;
}

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