// Copyright (C) 2005-2009 Angelo Naselli, Penta Engineering s.r.l.
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
// As a special exception, you may use this file as part of a free software
// library without restriction.  Specifically, if other files instantiate
// templates or use macros or inline functions from this file, or you compile
// this file and link it with other files to produce an executable, this
// file does not by itself cause the resulting executable to be covered by
// the GNU General Public License.  This exception does not however
// invalidate any other reasons why the executable file might be covered by
// the GNU General Public License.
//
// This exception applies only to the code released under the name GNU
// Common C++.  If you copy code from other releases into a copy of GNU
// Common C++, as the General Public License permits, the exception does
// not apply to the code that you add in this way.  To avoid misleading
// anyone as to the status of such modified files, you must delete
// this exception notice from them.
//
// If you write modifications of your own for GNU Common C++, it is your choice
// whether to permit this exception to apply to your modifications.
// If you do not wish that, delete this exception notice.
//

#include <cc++/config.h>
#include <cc++/thread.h>
#include <cc++/slog.h>
#include <cc++/buffer.h>
#include <string>
#include <iomanip>
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <stdarg.h>
#include <errno.h>

// TODO sc: test if has to move up now that it is into commoncpp
// NOTE: the order of inclusion is important do not move following include line
// redefinition of __EXPORT needed if we're compiling our dll
#include <cc++/export.h>
// local includes
#include <cc++/applog.h>

#ifdef  CCXX_NAMESPACES
using namespace std;
namespace ost
{
#endif


class logStruct
{
  public:
    string       _ident;
    int          _priority;
    Slog::Level  _level;
    bool         _enable;
    bool         _clogEnable;
    bool         _slogEnable;
    size_t       _msgpos;

    enum logEnum
    {
      BUFF_SIZE = 512,
      LAST_CHAR = BUFF_SIZE - 1
    };
    char         _msgbuf[BUFF_SIZE];

    logStruct() :  _ident("") ,  _priority(Slog::levelDebug),
        _level(Slog::levelDebug), _enable(false),
        _clogEnable(false), _slogEnable(false), _msgpos(0)
    {
      memset(_msgbuf, 0, BUFF_SIZE);
    };

    ~logStruct() {};
};

struct levelNamePair
{
  const char *name;
  Slog::Level level;
};

#ifdef WIN32
template class std::map<string, Slog::Level >;
#endif

class LevelName : public map<string, Slog::Level>
{
  public:

    LevelName(const levelNamePair initval[], int num)
    {
      for (int i = 0; i < num; i++)
        insert(make_pair(initval[i].name, initval[i].level));
    };
};

class logger : public ost::ThreadQueue
{
  private:
    string       _nomeFile;
    std::fstream _logfs;
    bool         _usePipe;

  protected:
    // to dequeue log messages and write them to file if not log_directly
    virtual void  runQueue(void *data);
    virtual void  startQueue(void);
    virtual void  stopQueue(void);
    virtual void  onTimer(void);
    virtual void  final(void);

  public:
    logger(const char* logFileName = NULL, bool usePipe = false);
    virtual ~logger();

    // To change log file name
    void logFileName(const char* FileName, bool usePipe = false);

};


// mapping thread ID <-> logStruct (buffer)
typedef map <cctid_t, logStruct> LogPrivateData;
// map ident <-> levels
typedef map <string, Slog::Level> IdentLevel;


class AppLogPrivate
{
  public:
    // subscription and unsubsciption must be protected as well
    ost::Mutex _subMutex;
    // mapping thread ID <-> logStruct (buffer)
    LogPrivateData _logs;
    // map ident <-> levels
    IdentLevel     _identLevel;
    // log directly into file
    bool           _logDirectly;
    bool           _logPipe;
    // log spooler
    logger         *_pLogger;

    string        _nomeFile;
    Mutex         _lock;
    std::fstream  _logfs;

    static const levelNamePair _values[];
    static LevelName           _assoc;

    AppLogPrivate() : _pLogger(NULL) {}

    ~AppLogPrivate()
    {
      if (_pLogger)
        delete _pLogger;
    }
};



const levelNamePair AppLogPrivate::_values[] =
{
  { "emerg", Slog::levelEmergency },
  { "alert", Slog::levelAlert },
  { "critical", Slog::levelCritical },
  { "error", Slog::levelError },
  { "warn", Slog::levelWarning },
  { "notice", Slog::levelNotice },
  { "info", Slog::levelInfo },
  { "debug", Slog::levelDebug }
};

AppLog alog;

LevelName AppLogPrivate::_assoc(_values, sizeof AppLogPrivate::_values / sizeof *AppLogPrivate::_values);
map<string, Slog::Level> *AppLog::assoc = &AppLogPrivate::_assoc;

HEXdump::HEXdump(const unsigned char *buffer, int len, int max_len) : _str()
{
  std::stringstream sstr;


  if (buffer == NULL || len <= 0)
    return ;

  long buf_len = (max_len > 0 && len > max_len) ? max_len : len;
  long int addr = 0;
  int cnt2 = 0;
  int n;
  int i;

  sstr.str("");
  // get exception from ifstream failures
  sstr.exceptions(ifstream::failbit | ifstream::badbit);
  try
  {
    sstr << std::endl;
    sstr << "dump " << len << " byte." << std::endl;

    for (n = 0; n < buf_len; n++)
    {
      if (cnt2 == 0)
      {
        //  Print address.
        sstr << std::setw(7) << std::setfill('0') <<  int (addr) << " - ";
        addr = addr + 16;
      }
      cnt2 = (cnt2 + 1) % 18;
      if (cnt2 <= 16)
      {
        // print hex value
        sstr << std::hex << std::setw(2) << std::setfill('0') <<  int (buffer[n]) << " ";
      }
      else
      {
        sstr << "  ";
        sstr << std::setfill(' ');
        for (i = n - cnt2 + 1; i < n; i++)
        {
          // print ascii value
          if (buffer[i] < 32 || 126 < buffer[i])
          {
            sstr << '.';
          }
          else
          {
            sstr << buffer[i];
          }
        }
        sstr << std::endl;
        sstr << std::dec;
        cnt2 = 0;
        n--;
      }
    }

    sstr << std::setfill(' ');

    for (i = cnt2 + 1; i <= 16 ; i++)
    {
      sstr << std::setw(2) << "--" << " ";
    }
    sstr << "  ";

    for (i = n - cnt2; cnt2 <= 16 && i < n; i++)
    {
      if (buffer[i] < 32 || 126 < buffer[i])
      {
        sstr << '.';
      }
      else
      {
        sstr << buffer[i];
      }
    }
    sstr << std::dec;
    if (max_len > 0 && len > max_len)
      sstr << std::endl << "dump troncato a " << max_len << " byte." << std::endl;
  }
  catch (...)
  {
    sstr.str("HEXdump failed!");
  }

  _str = sstr.str();
}

// class logger
logger::logger(const char* logFileName, bool usePipe)  : ThreadQueue(NULL, 0, 0), _usePipe(usePipe)
{
  _nomeFile = "";

  if (logFileName)
    _nomeFile = logFileName;
  if (!_nomeFile.empty())
  {
    if (!_usePipe)
    {
      _logfs.open(_nomeFile.c_str(), std::ofstream::out | std::ofstream::app | std::ofstream::ate);
    }
#ifndef WIN32
    else
    {
      // create pipe
      int err = mkfifo(_nomeFile.c_str(), S_IREAD | S_IWRITE);
      if (err == 0 || errno == EEXIST)
      {
        // and open it
        _logfs.open(_nomeFile.c_str(), std::fstream::in | std::fstream::out);
      }
      else
        THROW(AppLogException("Can't create pipe"));
    }
#endif
    if (_logfs.fail())
      THROW(AppLogException("Can't open log file name"));
  }
}

logger::~logger()
{
  Semaphore::post();
  Thread::terminate();

  _logfs.flush();
  _logfs.close();
}

// New log file name
void logger::logFileName(const char* FileName, bool usePipe)
{
  if (!FileName)
    return;

  _usePipe = usePipe;
  _nomeFile = FileName;
  if (_logfs.is_open())
    _logfs.close();

  if (!_nomeFile.empty())
  {
    if (!_usePipe)
    {
      _logfs.open(_nomeFile.c_str(), std::ofstream::out | std::ofstream::app | std::ofstream::ate);
    }
#ifndef WIN32
    else
    {
      // create pipe
      int err = mkfifo(_nomeFile.c_str(), S_IREAD | S_IWRITE);
      if (err == 0 || errno == EEXIST)
      {
        // and open it
        _logfs.open(_nomeFile.c_str(), std::fstream::in | std::fstream::out);
      }
      else
        THROW(AppLogException("Can't create pipe"));
    }
#endif
    if (_logfs.fail())
      THROW(AppLogException("Can't open log file name"));
  }

}

// writes into filename enqueued messages
void logger::runQueue(void * data)
{
  char *str = (char *) data;

  if (_logfs.is_open())
  {
    Thread::setCancel(cancelDisabled);
    _logfs << str;
    _logfs.flush();
    Thread::setCancel(cancelImmediate);
  }
}

void logger::startQueue()
{
  testCancel();
}

void logger::stopQueue()
{
  testCancel();
}

void logger::onTimer()
{
}

void logger::final()
{
  if (started)
  {
    data_t *pFirst = first;
    while (pFirst)
    {
      runQueue(pFirst->data);
      pFirst = pFirst->next;
    }
  }
}

#ifndef WIN32
AppLog::AppLog(const char* logFileName, bool logDirectly, bool usePipe) :
    streambuf(), ostream((streambuf*) this)
#else
AppLog::AppLog(const char* logFileName, bool logDirectly) :
    streambuf(), ostream((streambuf*) this)
#endif
{
  d= NULL; // pedantic fussy about initing members before base classes...
  d = new AppLogPrivate();
  if (!d)
    THROW(AppLogException("Memory allocation problem"));

  d->_nomeFile = "";
  d->_logDirectly = logDirectly;
#ifndef WIN32
  d->_logPipe = usePipe;
#else
  d->_logPipe = false;
#endif
  // level string to level value
  //   assoc["emerg"]    = levelEmergency;
  //   assoc["alert"]    = levelAlert;
  //   assoc["critical"] = levelCritical;
  //   assoc["error"]    = levelError;
  //   assoc["warn"]     = levelWarning;
  //   assoc["notice"]   = levelNotice;
  //   assoc["info"]     = levelInfo;
  //   assoc["debug"]    = levelDebug;

  if (logFileName)
    d->_nomeFile = logFileName;

  if (!d->_logDirectly && logFileName)
    d->_pLogger = new logger(logFileName, d->_logPipe);
  else
    d->_pLogger = NULL;

  // writes to file directly
  if (!d->_nomeFile.empty() && d->_logDirectly)
  {
    if (!d->_logPipe)
    {
      d->_logfs.open(d->_nomeFile.c_str(), std::fstream::in | std::fstream::out);

      if (!d->_logfs.is_open())
      {
        d->_logfs.open(d->_nomeFile.c_str(), std::fstream::out | std::fstream::app);
      }
      else
        d->_logfs.seekg(0, std::fstream::end);
    }
// on Windows pipe are not used as they are not supported on WinNT
#ifndef WIN32
    else
    {
      // create pipe
      int err = mkfifo(d->_nomeFile.c_str(), S_IREAD | S_IWRITE);
      if (err == 0 || errno == EEXIST)
      {
        // and open it
        d->_logfs.open(d->_nomeFile.c_str(), std::fstream::in | std::fstream::out);
      }
      else
        THROW(AppLogException("Can't create pipe"));
    }
#endif
    if (d->_logfs.fail())
      THROW(AppLogException("Can't open log file name"));
  }

  //from Error level on write to syslog also
  slog.level(Slog::levelError);
  slog.clogEnable(false);
}

AppLog::~AppLog()
{
  // if _logDirectly
  close();
  if (d) delete d;
}

void AppLog::subscribe()
{
  ost::MutexLock mtx(d->_subMutex);

  Thread *pThr = getThread();
  if (pThr)
  {
    cctid_t tid =  pThr->getId();

    LogPrivateData::iterator logIt = d->_logs.find(tid);
    if (logIt == d->_logs.end())
    {
      // subscribes new thread
      d->_logs[tid];
    }
  }
}

void AppLog::unsubscribe()
{
  ost::MutexLock mtx(d->_subMutex);

  Thread *pThr = getThread();
  if (pThr)
  {
    cctid_t tid =  pThr->getId();

    LogPrivateData::iterator logIt = d->_logs.find(tid);
    if (logIt != d->_logs.end())
    {
      // unsubscribes thread
      d->_logs.erase(logIt);
    }
  }
}

#ifndef WIN32
void AppLog::logFileName(const char* FileName, bool logDirectly, bool usePipe)
#else
void AppLog::logFileName(const char* FileName, bool logDirectly)
#endif
{
  if (!FileName)
  {
    slog.error("Null file name!");
    return;
  }

  d->_lock.enterMutex();
  d->_nomeFile = FileName;
  close();
  d->_logDirectly = logDirectly;
#ifndef WIN32
  d->_logPipe = usePipe;
#else
  d->_logPipe = false;
#endif
  if (!d->_logDirectly)
  {
    d->_nomeFile = FileName;
    if (d->_pLogger)
      d->_pLogger->logFileName(FileName, d->_logPipe);
    else
      d->_pLogger = new logger(FileName, d->_logPipe);

    d->_lock.leaveMutex();
    return;
  }

  // log directly
  if (!d->_nomeFile.empty())
  {
    if (!d->_logPipe)
    {
      d->_logfs.open(d->_nomeFile.c_str(), std::fstream::out | std::fstream::app);
    }
#ifndef WIN32
    else
    {
      // create pipe
      int err = mkfifo(d->_nomeFile.c_str(), S_IREAD | S_IWRITE);
      if (err == 0 || errno == EEXIST)
      {
        // and open it
        d->_logfs.open(d->_nomeFile.c_str(), std::fstream::in | std::fstream::out);
      }
      else
        THROW(AppLogException("Can't create pipe"));
    }
#endif
    if (d->_logfs.fail())
      THROW(AppLogException("Can't open log file name"));
  }
  d->_lock.leaveMutex();
}

// writes to log
void AppLog::writeLog(bool endOfLine)
{
  Thread *pThr = getThread();
  if (pThr)
  {
    cctid_t tid =  pThr->getId();

    LogPrivateData::iterator logIt = d->_logs.find(tid);
    if (logIt == d->_logs.end())
      return;

    if ((d->_logDirectly && !d->_logfs.is_open() && !logIt->second._clogEnable) ||
        (!d->_logDirectly && !d->_pLogger && !logIt->second._clogEnable))

    {
      logIt->second._msgpos = 0;
      logIt->second._msgbuf[0] = '\0';
      return;
    }

    if (logIt->second._enable)
    {
      time_t now;
      struct tm *dt;
      time(&now);
      struct timeval detail_time;
      gettimeofday(&detail_time, NULL);
      dt = localtime(&now);
      char buf[50];

      const char *p = "unknown";
      switch (logIt->second._priority)
      {
        case Slog::levelEmergency:
          p = "emerg";
          break;
        case Slog::levelInfo:
          p = "info";
          break;
        case Slog::levelError:
          p = "error";
          break;
        case Slog::levelAlert:
          p = "alert";
          break;
        case Slog::levelDebug:
          p = "debug";
          break;
        case Slog::levelNotice:
          p = "notice";
          break;
        case Slog::levelWarning:
          p = "warn";
          break;
        case Slog::levelCritical:
          p = "crit";
          break;
      }

      snprintf(buf, sizeof(buf) - 1, "%04d-%02d-%02d %02d:%02d:%02d.%03d ",
               dt->tm_year + 1900, dt->tm_mon + 1, dt->tm_mday,
               dt->tm_hour, dt->tm_min, dt->tm_sec, (int)(detail_time.tv_usec / 1000));

      buf[sizeof(buf)-1] = 0;    // per sicurezza

      if (d->_logDirectly)
      {
        d->_lock.enterMutex();
        if (d->_logfs.is_open())
        {
          d->_logfs << buf;
          if (!logIt->second._ident.empty())
            d->_logfs << logIt->second._ident.c_str() << ": ";
          d->_logfs << "[" << p << "] ";

          d->_logfs << logIt->second._msgbuf;

          if (endOfLine)
            d->_logfs << endl;

          d->_logfs.flush();
        }
      }
      else if (d->_pLogger)
      {
        // ThreadQueue
        std::stringstream sstr;
        sstr.str("");    // reset contents
        sstr << buf;

        if (!logIt->second._ident.empty())
          sstr << logIt->second._ident.c_str() << ": ";
        sstr << "[" << p << "] ";

        sstr << logIt->second._msgbuf;
        if (endOfLine)
          sstr << endl;
        sstr.flush();

        if (sstr.fail())
          cerr << "stringstream failed!!!! " << endl;

        // enqueues log message
        d->_pLogger->post((void *) sstr.str().c_str(), sstr.str().length() + 1);

        d->_lock.enterMutex();
      }

      // slog it if error level is right
      if (logIt->second._slogEnable && logIt->second._priority <= Slog::levelError)
      {
        slog((Slog::Level) logIt->second._priority) << logIt->second._msgbuf;
        if (endOfLine) slog << endl;
      }
      if (logIt->second._clogEnable
#ifndef WIN32
          && (getppid() > 1)
#endif
         )
      {
        clog << logIt->second._msgbuf;
        if (endOfLine)
          clog << endl;
      }

      d->_lock.leaveMutex();
    }

    logIt->second._msgpos = 0;
    logIt->second._msgbuf[0] = '\0';
  }
}

void AppLog::close(void)
{
  if (d->_logDirectly)
  {
    d->_lock.enterMutex();
    if (d->_logfs.is_open())
    {
      d->_logfs.flush();
      d->_logfs.close();
    }
    d->_lock.leaveMutex();
  }
}

void AppLog::open(const char *ident)
{
  Thread *pThr = getThread();
  if (pThr)
  {
    cctid_t tid =  pThr->getId();

    LogPrivateData::iterator logIt = d->_logs.find(tid);
    if (logIt == d->_logs.end())
      return;

    if (d->_nomeFile.empty())
    {
      std::cerr << "Empty file name" << std::endl;
      slog.emerg("Empty file nane!\n");
    }
    if (d->_logDirectly)
    {
      d->_lock.enterMutex();
      if (!d->_logfs.is_open())
      {
        d->_logfs.open(d->_nomeFile.c_str(), std::fstream::out | std::fstream::app);
      }
      if (!d->_logfs.is_open())
      {
        std::cerr << "Can't open file name!" << std::endl;
        slog.emerg("Can't open file name!\n");
      }
      d->_lock.leaveMutex();
    }
    if (ident != NULL)
      logIt->second._ident = ident;

  }
}

void AppLog::identLevel(const char *ident, Slog::Level level)
{
  if (!ident)
    return;

  string id = ident;

  IdentLevel::iterator idLevIt = d->_identLevel.find(id);
  if (idLevIt == d->_identLevel.end())
  {
    d->_identLevel[id] = level;
  }
  else
    idLevIt->second = level;

}

void AppLog::level(Slog::Level enable)
{
  Thread *pThr = getThread();
  if (pThr)
  {
    cctid_t tid =  pThr->getId();

    LogPrivateData::iterator logIt = d->_logs.find(tid);
    if (logIt == d->_logs.end())
      return;
    logIt->second._level = enable;
  }
}

void AppLog::clogEnable(bool f)
{
  Thread *pThr = getThread();
  if (pThr)
  {
    cctid_t tid =  pThr->getId();

    LogPrivateData::iterator logIt = d->_logs.find(tid);
    if (logIt == d->_logs.end())
      return;
    logIt->second._clogEnable = f;
  }
}

void AppLog::slogEnable(bool en)
{
  Thread *pThr = getThread();
  if (pThr)
  {
    cctid_t tid =  pThr->getId();

    LogPrivateData::iterator logIt = d->_logs.find(tid);
    if (logIt == d->_logs.end())
      return;

    logIt->second._slogEnable = en;
  }
}

int AppLog::sync()
{
  int retVal = (pbase() != pptr());

  if (fail())
  {
    slog(Slog::levelNotice) << "fail() is true, calling clear()" << endl;
    clear();
  }

  Thread *pThr = getThread();
  if (pThr)
  {
    cctid_t tid =  pThr->getId();
    LogPrivateData::iterator logIt = d->_logs.find(tid);
    if (logIt != d->_logs.end())
    {
      retVal = (logIt->second._msgpos > 0);
      if (retVal)
      {
        slog(Slog::levelNotice) << "sync called and msgpos > 0" << endl;
      }
    }
  }

  overflow(EOF);

  return retVal;

}

int AppLog::overflow(int c)
{
  Thread *pThr = getThread();
  if (pThr)
  {
    cctid_t tid =  pThr->getId();

    LogPrivateData::iterator logIt = d->_logs.find(tid);
    if (logIt == d->_logs.end())
      return c;
    if (!logIt->second._enable)
      return c;

    if (c == '\n' || !c || c == EOF)
    {
      if (!logIt->second._msgpos)
      {
        if (c == '\n') writeLog(true);
        return c;
      }
      if (logIt->second._msgpos < (int)(sizeof(logIt->second._msgbuf) - 1))
        logIt->second._msgbuf[logIt->second._msgpos] = 0;
      else
        logIt->second._msgbuf[logIt->second._msgpos-1] = 0;

      writeLog(c == '\n');
      //reset buffer
      logIt->second._msgpos = 0;

      return c;
    }

    if (logIt->second._msgpos < (int)(sizeof(logIt->second._msgbuf) - 1))
      logIt->second._msgbuf[logIt->second._msgpos++] = c;

  }

  return c;
}

#ifdef  HAVE_SNPRINTF

void AppLog::error(const char *format, ...)
{
  va_list args;

  Thread *pThr = getThread();
  if (pThr)
  {
    cctid_t tid =  pThr->getId();

    LogPrivateData::iterator logIt = d->_logs.find(tid);
    if (logIt == d->_logs.end())
      return;

    error();
    if (!logIt->second._enable)
      return;
    overflow(EOF);

    va_start(args, format);
    logIt->second._msgbuf[logStruct::BUFF_SIZE-1] = '\0';
    logIt->second._msgpos = vsnprintf(logIt->second._msgbuf, logStruct::BUFF_SIZE, format, args);
    if (logIt->second._msgpos > logStruct::BUFF_SIZE - 1) logIt->second._msgpos = logStruct::BUFF_SIZE - 1;
    overflow(EOF);
    if (logIt->second._slogEnable)
      slog.error(logIt->second._msgbuf);
    va_end(args);
  }
}

void AppLog::warn(const char *format, ...)
{
  va_list args;

  Thread *pThr = getThread();
  if (pThr)
  {
    cctid_t tid =  pThr->getId();

    LogPrivateData::iterator logIt = d->_logs.find(tid);
    if (logIt == d->_logs.end())
      return;

    warn();
    if (!logIt->second._enable)
      return;
    overflow(EOF);

    va_start(args, format);
    logIt->second._msgbuf[logStruct::BUFF_SIZE-1] = '\0';
    logIt->second._msgpos = vsnprintf(logIt->second._msgbuf, logStruct::BUFF_SIZE, format, args);
    if (logIt->second._msgpos > logStruct::BUFF_SIZE - 1) logIt->second._msgpos = logStruct::BUFF_SIZE - 1;
    overflow(EOF);
    if (logIt->second._slogEnable)
      slog.warn(logIt->second._msgbuf);
    va_end(args);
  }
}

void AppLog::debug(const char *format, ...)
{
  va_list args;

  Thread *pThr = getThread();
  if (pThr)
  {
    cctid_t tid =  pThr->getId();

    LogPrivateData::iterator logIt = d->_logs.find(tid);
    if (logIt == d->_logs.end())
      return;

    debug();
    if (!logIt->second._enable)
      return;
    overflow(EOF);

    va_start(args, format);
    logIt->second._msgbuf[logStruct::BUFF_SIZE-1] = '\0';
    logIt->second._msgpos = vsnprintf(logIt->second._msgbuf, logStruct::BUFF_SIZE, format, args);
    if (logIt->second._msgpos > logStruct::BUFF_SIZE - 1) logIt->second._msgpos = logStruct::BUFF_SIZE - 1;
    overflow(EOF);
    va_end(args);
  }
}

void AppLog::emerg(const char *format, ...)
{
  va_list args;

  Thread *pThr = getThread();
  if (pThr)
  {
    cctid_t tid =  pThr->getId();

    LogPrivateData::iterator logIt = d->_logs.find(tid);
    if (logIt == d->_logs.end())
      return;

    emerg();
    if (!logIt->second._enable)
      return;
    overflow(EOF);

    va_start(args, format);
    logIt->second._msgbuf[logStruct::BUFF_SIZE-1] = '\0';
    logIt->second._msgpos = vsnprintf(logIt->second._msgbuf, logStruct::BUFF_SIZE, format, args);
    if (logIt->second._msgpos > logStruct::BUFF_SIZE - 1) logIt->second._msgpos = logStruct::BUFF_SIZE - 1;
    overflow(EOF);
    if (logIt->second._slogEnable)
      slog.emerg(logIt->second._msgbuf);
    va_end(args);
  }
}

void AppLog::alert(const char *format, ...)
{
  va_list args;

  Thread *pThr = getThread();
  if (pThr)
  {
    cctid_t tid =  pThr->getId();

    LogPrivateData::iterator logIt = d->_logs.find(tid);
    if (logIt == d->_logs.end())
      return;

    alert();
    if (!logIt->second._enable)
      return;
    overflow(EOF);

    va_start(args, format);
    logIt->second._msgbuf[logStruct::BUFF_SIZE-1] = '\0';
    logIt->second._msgpos = vsnprintf(logIt->second._msgbuf, logStruct::BUFF_SIZE, format, args);
    if (logIt->second._msgpos > logStruct::BUFF_SIZE - 1) logIt->second._msgpos = logStruct::BUFF_SIZE - 1;
    overflow(EOF);
    if (logIt->second._slogEnable)
      slog.alert(logIt->second._msgbuf);
    va_end(args);
  }
}

void AppLog::critical(const char *format, ...)
{
  va_list args;

  Thread *pThr = getThread();
  if (pThr)
  {
    cctid_t tid =  pThr->getId();

    LogPrivateData::iterator logIt = d->_logs.find(tid);
    if (logIt == d->_logs.end())
      return;

    critical();
    if (!logIt->second._enable)
      return;
    overflow(EOF);

    va_start(args, format);
    logIt->second._msgbuf[logStruct::BUFF_SIZE-1] = '\0';
    logIt->second._msgpos = vsnprintf(logIt->second._msgbuf, logStruct::BUFF_SIZE, format, args);
    if (logIt->second._msgpos > logStruct::BUFF_SIZE - 1) logIt->second._msgpos = logStruct::BUFF_SIZE - 1;
    overflow(EOF);
    if (logIt->second._slogEnable)
      slog.critical(logIt->second._msgbuf);
    va_end(args);
  }
}

void AppLog::notice(const char *format, ...)
{
  va_list args;

  Thread *pThr = getThread();
  if (pThr)
  {
    cctid_t tid =  pThr->getId();

    LogPrivateData::iterator logIt = d->_logs.find(tid);
    if (logIt == d->_logs.end())
      return;

    notice();
    if (!logIt->second._enable)
      return;
    overflow(EOF);

    va_start(args, format);
    logIt->second._msgbuf[logStruct::BUFF_SIZE-1] = '\0';
    logIt->second._msgpos = vsnprintf(logIt->second._msgbuf, logStruct::BUFF_SIZE, format, args);
    if (logIt->second._msgpos > logStruct::BUFF_SIZE - 1) logIt->second._msgpos = logStruct::BUFF_SIZE - 1;
    overflow(EOF);
    if (logIt->second._slogEnable)
      slog.notice(logIt->second._msgbuf);
    va_end(args);
  }
}

void AppLog::info(const char *format, ...)
{
  va_list args;

  Thread *pThr = getThread();
  if (pThr)
  {
    cctid_t tid =  pThr->getId();

    LogPrivateData::iterator logIt = d->_logs.find(tid);
    if (logIt == d->_logs.end())
      return;

    info();
    if (!logIt->second._enable)
      return;
    overflow(EOF);

    va_start(args, format);
    logIt->second._msgbuf[logStruct::BUFF_SIZE-1] = '\0';
    logIt->second._msgpos = vsnprintf(logIt->second._msgbuf, logStruct::BUFF_SIZE, format, args);
    if (logIt->second._msgpos > logStruct::BUFF_SIZE - 1) logIt->second._msgpos = logStruct::BUFF_SIZE - 1;
    overflow(EOF);
    va_end(args);
  }
}

#endif //HAVE_SNPRINTF

AppLog &AppLog::operator()(Slog::Level lev)
{
  Thread *pThr = getThread();
  if (pThr)
  {
    cctid_t tid =  pThr->getId();

    LogPrivateData::iterator logIt = d->_logs.find(tid);
    if (logIt == d->_logs.end())
      return *this;

    // needed? overflow(EOF);

    // enables log
    Slog::Level th_lev = logIt->second._level;
    logIt->second._enable = (th_lev >= lev);
    // is there a log level per module?
    if (!logIt->second._ident.empty())
    {
      std::string st = logIt->second._ident;
      IdentLevel::iterator idLevIt = d->_identLevel.find(st);
      if (idLevIt != d->_identLevel.end())
      {
        th_lev = idLevIt->second;
        logIt->second._enable = (th_lev >= lev);
      }
    }

    logIt->second._priority = lev;
  }

  return *this;
}

AppLog &AppLog::operator()(const char *ident, Slog::Level lev)
{
  Thread *pThr = getThread();
  if (pThr)
  {
    cctid_t tid =  pThr->getId();

    LogPrivateData::iterator logIt = d->_logs.find(tid);
    if (logIt == d->_logs.end())
      return this->operator()(lev);

    logIt->second._enable =  true;
    open(ident);
  }

  return this->operator()(lev);
}


AppLog& AppLog::operator<< (AppLog& (*pfManipulator)(AppLog&))
{
  return (*pfManipulator)(*this);
}

AppLog& AppLog::operator<< (ostream& (*pfManipulator)(ostream&))
{
  (*pfManipulator)(*(dynamic_cast<ostream*>(this)));

  return  *this ;
}


#ifdef  CCXX_NAMESPACES
}
#endif

