#include "logger.h"
#include "functions.h"
#include "format.h"
#include <functional>
#include <iterator>
#include <sstream>
#include <algorithm>
#include <cerrno>

namespace proctools
{

   using namespace std;

   logger::manager logger::m_manager;

   class logwriter {
   public:
      logwriter(logger::loglevel level, const string& message):
      m_level(level), m_message(message) {}
      void operator()(logger* logger) { logger->log(m_level, m_message);}

   private:
      logger::loglevel m_level;
      const string& m_message;
   };

   logger::manager::~manager()
   {
      m_shutdown = true;
      for_each(m_loggers.begin(), m_loggers.end(), &deleter<logger>);
   }

   void logger::manager::message(loglevel level, const string& message)
   {
      for_each(m_loggers.begin(), m_loggers.end(),
               logwriter(level, message));
   }

   logger::logger()
   {
      m_manager += this;
   }

   logger::~logger()
   {
      m_manager -= this;
   }

   void logger::error(const string& message, bool add_syserror)
   {
      if( !add_syserror )
         m_manager.message(level_error, message);
      else
         m_manager.message(level_error,
                           format("{0}: {1}") % message % strerror(errno));
   }

   void logger::warning(const string& message)
   {
      m_manager.message(level_warning, message);
   }

   void logger::info(const string& message)
   {
      m_manager.message(level_info, message);
   }

   void logger::debug(const string& message)
   {
      m_manager.message(level_debug, message);
   }

   void logger::text(const string& message)
   {
      m_manager.message(level_text, message);
   }

};
