#include "clog.h"
#include "cfg.h"
#include "php_wrenchboard_log.h"

#include <gelfcpp/output/GelfUDPOutput.hpp>

#include <gelfcpp/decorator/StaticDecoratorSet.hpp>
#include <gelfcpp/decorator/Timestamp.hpp>
#include <gelfcpp/decorator/Host.hpp>

using namespace gelfcpp::output;

TLogLevel global_log_level = FLOG_MAX; // By default log everything

GelfUDPOutput *graylog;
using Decorator = gelfcpp::decorator::StaticDecoratorSet<gelfcpp::decorator::CurrentTimestamp, gelfcpp::decorator::Host>;
Decorator decorator;

void logfmt( TLogLevel level, const char * format, ... ) {
  if (level > global_log_level) {
    return; // We do not log messages greater than global log level!
  }
  size_t n = 32678;
  char buffer[n];
  bzero(buffer, n);
  try {
    //FILELog::ReportingLevel() = level;
    va_list args;
    va_start (args, format);
    if (level > FILELOG_MAX_LEVEL) ;
    else if (level > FILELog::ReportingLevel() || !Output2FILE::Stream()) ;
    else {
      FILE *f = Output2FILE::Stream();
      fprintf(f, "- %s %s [%ld]: %c", 
        NowTime().c_str(), 
        FILELog::ToString(level).c_str(),
        getpid(),
        (level > logDEBUG ? level - logDEBUG : 0, '\t'));
      vsnprintf (buffer, n, format, args);
      fprintf(f, buffer);
      fprintf(f, "\n");
    }
    va_end (args);
    // Graylog
    if (strlen(buffer) > 0) {
      if (graylog) {
        GELF_MESSAGE(*graylog)(decorator)
                        (buffer)
                        ("pid", getpid())
                        ("loglevel", FILELog::ToString(level).c_str());
      } else {
        FILE_LOG(logERROR) << "graylog is null!" ;
      }
    } else {
      FILE_LOG(logERROR) << "buffer length is " << strlen(buffer) ;   
    }// */
  } catch(const std::exception& e) {
    FILE_LOG(logERROR) << e.what();
  }
}
/*
void logfmt( TLogLevel level, const char * format, ... ) {
  try {
    //FILELog::ReportingLevel() = level;
    char buffer[2048];
    va_list args;
    va_start (args, format);
    vsprintf (buffer, format, args);
    //perror (buffer);
    va_end (args);
    FILE_LOG(level) << buffer;
  } catch(const std::exception& e) {
    FILE_LOG(logERROR) << e.what();
  }
}
*/

void GraylogStream(TLogLevel level, std::string raw) {
  if (!graylog) {
    std::cerr << "graylog is null!"; // We cannot use log here as it will go recursive
    return; // Not initialized, yet?
  }
  if (!raw.empty()) {
    /* GELF_MESSAGE(*graylog)(decorator)
                      (raw.c_str()); 
                      ("pid", getpid())
                      ("loglevel", "FLOG_MAX"); */

    std::string marker ("]: ");

    std::size_t found = raw.find(marker);
    if (found != std::string::npos) {
        std::string msg = raw.substr (found + 3);
        std::string levelString = FILELog::ToString(level);

        if (!msg.empty()) {
            GELF_MESSAGE(*graylog)(decorator)
                            (msg.c_str()) 
                            ("pid", getpid())
                            ("loglevel", levelString.c_str());
        } else {
          std::cerr << "Message is empty!";
        }
    } else {
      std::cerr << "Marker '" << marker << "' was not found!";
    }
    // */
  } else {
    std::cerr << "Raw message is empty!";
  }
}
// */

