/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <cctype>
#include <string>
#include <utility>
#include <vector>
#include <thread>
#include <chrono>

#include <ace/ACE.h>
#include <ace/Guard_T.h>
#include <ace/Thread_Mutex.h>
#include <ace/OS.h>
#include <ace/OS_NS_time.h>
#include <ace/OS_NS_sys_time.h>
#include <ace/OS_NS_unistd.h>
#include <ace/OS_NS_Thread.h>
#include <ace/Dirent.h>
#include <ace/Dirent_Selector.h>
#include <ace/OS_NS_sys_stat.h>

#include <geode/internal/geode_globals.hpp>
#include <geode/ExceptionTypes.hpp>
#include <geode/util/LogLevel.hpp>

#include "util/Log.hpp"
#include "geodeBanner.hpp"
#include "Assert.hpp"

#if defined(_WIN32)
#include <io.h>
#define GF_FILEEXISTS(x) _access_s(x, 00)
#else
#include <unistd.h>
#define GF_FILEEXISTS(x) access(x, F_OK)
#endif

/*****************************************************************************/

/**
 * The implementation of the Log class
 *
 *
 */

/*****************************************************************************/

namespace apache {
namespace geode {
namespace log {
namespace globals {

std::string* g_logFile = nullptr;
std::string* g_logFileWithExt = nullptr;

size_t g_bytesWritten = 0;
bool g_isLogFileOpened = false;

size_t g_fileSizeLimit = GEODE_MAX_LOG_FILE_LIMIT;
size_t g_diskSpaceLimit = GEODE_MAX_LOG_DISK_LIMIT;

char g_logFileNameBuffer[2048] = {0};

ACE_Thread_Mutex* g_logMutex = new ACE_Thread_Mutex("Log::logMutex");

int g_rollIndex = 0;
size_t g_spaceUsed = 0;
// Make a pair for the filename & its size
std::pair<std::string, int64_t> g_fileInfoPair;
// Vector to hold the fileInformation
typedef std::vector<std::pair<std::string, int64_t> > g_fileInfo;

FILE* g_log = nullptr;
ACE_utsname g_uname;
pid_t g_pid = 0;

}  // namespace globals
}  // namespace log
}  // namespace geode
}  // namespace apache

extern "C" {

static int selector(const dirent* d) {
  std::string inputname(d->d_name);
  std::string filebasename =
      ACE::basename(apache::geode::log::globals::g_logFileWithExt->c_str());
  size_t actualHyphenPos = filebasename.find_last_of('.');
  if (strcmp(filebasename.c_str(), d->d_name) == 0) return 1;
  size_t fileExtPos = inputname.find_last_of('.');
  std::string extName = inputname.substr(fileExtPos + 1, inputname.length());
  if (strcmp(extName.c_str(), "log") != 0) return 0;
  if (fileExtPos != std::string::npos) {
    std::string tempname = inputname.substr(0, fileExtPos);
    size_t fileHyphenPos = tempname.find_last_of('-');
    if (fileHyphenPos != std::string::npos) {
      std::string buff1 = tempname.substr(0, fileHyphenPos);
      if (strstr(filebasename.c_str(), buff1.c_str()) == nullptr) {
        return 0;
      }
      if (fileHyphenPos != actualHyphenPos) return 0;
      std::string buff = tempname.substr(fileHyphenPos + 1,
                                         tempname.length() - fileHyphenPos - 1);
      for (std::string::iterator iter = buff.begin(); iter != buff.end();
           ++iter) {
        if (*iter < '0' || *iter > '9') {
          return 0;
        }
      }
      return 1;
    } else {
      return 0;
    }
  } else {
    return 0;
  }
}

static int comparator(const dirent** d1, const dirent** d2) {
  if (strlen((*d1)->d_name) < strlen((*d2)->d_name)) {
    return -1;
  } else if (strlen((*d1)->d_name) > strlen((*d2)->d_name)) {
    return 1;
  }

  int diff = ACE_OS::strcmp((*d1)->d_name, (*d2)->d_name);
  if (diff < 0) {
    return -1;
  } else if (diff > 0) {
    return 1;
  } else {
    return 0;
  }
}
}

namespace apache {
namespace geode {
namespace client {

LogLevel Log::s_logLevel = LogLevel::Default;

using apache::geode::log::globals::g_bytesWritten;
using apache::geode::log::globals::g_diskSpaceLimit;
using apache::geode::log::globals::g_fileInfo;
using apache::geode::log::globals::g_fileInfoPair;
using apache::geode::log::globals::g_fileSizeLimit;
using apache::geode::log::globals::g_isLogFileOpened;
using apache::geode::log::globals::g_log;
using apache::geode::log::globals::g_logFile;
using apache::geode::log::globals::g_logFileNameBuffer;
using apache::geode::log::globals::g_logFileWithExt;
using apache::geode::log::globals::g_logMutex;
using apache::geode::log::globals::g_pid;
using apache::geode::log::globals::g_rollIndex;
using apache::geode::log::globals::g_spaceUsed;
using apache::geode::log::globals::g_uname;

/*****************************************************************************/

const char* Log::logFileName() {
  ACE_Guard<ACE_Thread_Mutex> guard(*g_logMutex);

  if (!g_logFile) {
    g_logFileNameBuffer[0] = '\0';
  } else {
    if (g_logFile->size() >= sizeof g_logFileNameBuffer) {
      throw IllegalStateException(
          ("Log file name is too long: " + *g_logFile).c_str());
    }
    ACE_OS::strncpy(g_logFileNameBuffer, g_logFile->c_str(),
                    sizeof(g_logFileNameBuffer));
  }

  return g_logFileNameBuffer;
}

void Log::init(LogLevel level, const char* logFileName, int32_t logFileLimit,
               int64_t logDiskSpaceLimit) {
  if (g_log != nullptr) {
    throw IllegalStateException(
        "The Log has already been initialized. "
        "Call Log::close() before calling Log::init again.");
  }
  s_logLevel = level;
  if (g_logMutex == nullptr) g_logMutex = new ACE_Thread_Mutex("Log::logMutex");

  if (logDiskSpaceLimit <
      0 /*|| logDiskSpaceLimit > GEODE_MAX_LOG_DISK_LIMIT*/) {
    logDiskSpaceLimit = GEODE_MAX_LOG_DISK_LIMIT;
  }

  if (logFileLimit < 0 || logFileLimit > GEODE_MAX_LOG_FILE_LIMIT) {
    logFileLimit = GEODE_MAX_LOG_FILE_LIMIT;
  }

  ACE_Guard<ACE_Thread_Mutex> guard(*g_logMutex);

  if (logFileName && logFileName[0]) {
    std::string filename = logFileName;
    if (filename.size() >= sizeof g_logFileNameBuffer) {
      throw IllegalStateException(
          ("Log file name is too long: " + filename).c_str());
    }
    if (g_logFile) {
      *g_logFile = filename;
    } else {
      g_logFile = new std::string(filename);
    }

#ifdef _WIN32
    // replace all '\' with '/' to make everything easier..
    size_t length = g_logFile->length() + 1;
    char* slashtmp = new char[length];
    ACE_OS::strncpy(slashtmp, g_logFile->c_str(), length);
    for (size_t i = 0; i < g_logFile->length(); i++) {
      if (slashtmp[i] == '/') {
        slashtmp[i] = '\\';
      }
    }
    *g_logFile = slashtmp;
    delete[] slashtmp;
    slashtmp = nullptr;
#endif

    // Appending a ".log" at the end if it does not exist or file has some other
    // extension.
    std::string filebasename = ACE::basename(g_logFile->c_str());
    int32_t len = static_cast<int32_t>(filebasename.length());
    size_t fileExtPos = filebasename.find_last_of('.', len);
    // if no extension then add .log extension
    if (fileExtPos == std::string::npos) {
      g_logFileWithExt = new std::string(*g_logFile + ".log");
    } else {
      std::string extName = filebasename.substr(fileExtPos + 1);
      // if extension other than .log change it to ext + .log
      if (extName != "log") {
        g_logFileWithExt = new std::string(*g_logFile + ".log");
      }
      // .log Extension already provided, no need to append any extension.
      else {
        g_logFileWithExt = new std::string(*g_logFile);
      }
    }

    g_fileSizeLimit = logFileLimit * 1024 * 1024;
    g_diskSpaceLimit = logDiskSpaceLimit * 1024ll * 1024ll;

    // If FileSizelimit is greater than DiskSpaceLimit & diskspaceLimit is set,
    // then set DiskSpaceLimit to FileSizelimit
    if (g_fileSizeLimit > g_diskSpaceLimit && g_diskSpaceLimit != 0) {
      g_fileSizeLimit = g_diskSpaceLimit;
    }

    // If only DiskSpaceLimit is specified and no FileSizeLimit specified, then
    // set DiskSpaceLimit to FileSizelimit.
    // This helps in getting the file handle that is exceeded the limit.
    if (g_fileSizeLimit == 0 && g_diskSpaceLimit != 0) {
      g_fileSizeLimit = g_diskSpaceLimit;
    }

    g_bytesWritten = 0;
    g_spaceUsed = 0;
    g_rollIndex = 0;

    std::string dirname = ACE::dirname(g_logFile->c_str());

    ACE_Dirent_Selector sds;
    int status = sds.open(dirname.c_str(), selector, comparator);
    if (status != -1) {
      for (int index = 0; index < sds.length(); ++index) {
        std::string strname = ACE::basename(sds[index]->d_name);
        size_t fileExtPos = strname.find_last_of('.', strname.length());
        if (fileExtPos != std::string::npos) {
          std::string tempname = strname.substr(0, fileExtPos);
          size_t fileHyphenPos = tempname.find_last_of('-', tempname.length());
          if (fileHyphenPos != std::string::npos) {
            std::string buff =
                tempname.substr(fileHyphenPos + 1, tempname.length());
            g_rollIndex = ACE_OS::atoi(buff.c_str()) + 1;
          }
        }  // if loop
      }    // for loop
    }
    sds.close();

    FILE* existingFile = fopen(g_logFileWithExt->c_str(), "r");
    if (existingFile != nullptr && logFileLimit > 0) {
      /* adongre
       * Coverity - II
       * CID 29205: Calling risky function (SECURE_CODING)[VERY RISKY]. Using
       * "sprintf" can cause a
       * buffer overflow when done incorrectly. Because sprintf() assumes an
       * arbitrarily long string,
       * callers must be careful not to overflow the actual space of the
       * destination.
       * Use snprintf() instead, or correct precision specifiers.
       * Fix : using ACE_OS::snprintf
       */
      char rollFile[1024] = {0};
      std::string logsdirname;
      std::string logsbasename;
      std::string fnameBeforeExt;
      std::string extName;
      std::string newfilestr;

      int32_t len = static_cast<int32_t>(g_logFileWithExt->length());
      int32_t lastPosOfSep = static_cast<int32_t>(
          g_logFileWithExt->find_last_of(ACE_DIRECTORY_SEPARATOR_CHAR, len));
      if (lastPosOfSep == -1) {
        logsdirname = ".";
      } else {
        logsdirname = g_logFileWithExt->substr(0, lastPosOfSep);
      }
      logsbasename = g_logFileWithExt->substr(lastPosOfSep + 1, len);
      char logFileExtAfter = '.';
      int32_t baselen = static_cast<int32_t>(logsbasename.length());
      int32_t posOfExt = static_cast<int32_t>(
          logsbasename.find_last_of(logFileExtAfter, baselen));
      if (posOfExt == -1) {
        // throw IllegalArgument;
      } else {
        fnameBeforeExt = logsbasename.substr(0, posOfExt);
        extName = logsbasename.substr(posOfExt + 1, baselen);
      }
      ACE_OS::snprintf(rollFile, 1024, "%s%c%s-%d.%s", logsdirname.c_str(),
                       ACE_DIRECTORY_SEPARATOR_CHAR, fnameBeforeExt.c_str(),
                       g_rollIndex++, extName.c_str());
      bool rollFileNameGot = false;
      while (!rollFileNameGot) {
        FILE* checkFile = fopen(rollFile, "r");
        if (checkFile != nullptr) {
          fclose(checkFile);
          checkFile = nullptr;
          ACE_OS::snprintf(rollFile, 1024, "%s%c%s-%d.%s", logsdirname.c_str(),
                           ACE_DIRECTORY_SEPARATOR_CHAR, fnameBeforeExt.c_str(),
                           g_rollIndex++, extName.c_str());
        } else {
          rollFileNameGot = true;
        }
        /* adongre
         * CID 28999: Use after free (USE_AFTER_FREE)
         */
        if (checkFile != nullptr) fclose(existingFile);
      }
      // retry some number of times before giving up when file is busy etc.
      int renameResult = -1;
      int maxTries = 10;
      while (maxTries-- > 0) {
        renameResult = ACE_OS::rename(g_logFileWithExt->c_str(), rollFile);
        if (renameResult >= 0) {
          break;
        }
        // continue after some sleep
        std::this_thread::sleep_for(std::chrono::milliseconds(200));
      }
      /* (don't throw exception; try appending to existing file instead)
      if (renameResult < 0) {
        std::string msg = "Could not rename: " +
          *g_logFileWithExt + " to: " + rollFile;
        throw GeodeIOException(msg.c_str());
      }
      */
    }
    if (existingFile != nullptr) {
      fclose(existingFile);
      existingFile = nullptr;
    }
  } else if (g_logFile) {
    delete g_logFile;
    g_logFile = nullptr;
    g_logFileWithExt = nullptr;
  }
  writeBanner();
}

void Log::close() {
  ACE_Guard<ACE_Thread_Mutex> guard(*g_logMutex);

  std::string oldfile;

  if (g_logFile) {
    oldfile = *g_logFile;
    delete g_logFile;
    g_logFile = nullptr;
  }
  if (g_logFileWithExt) {
    delete g_logFileWithExt;
    g_logFileWithExt = nullptr;
  }

  if (g_log) {
    fclose(g_log);
    g_log = nullptr;
  }
}

void Log::writeBanner() {
  if (g_logFileWithExt == nullptr) {
    return;
  }
  const char* dirname = ACE::dirname(g_logFileWithExt->c_str());
  if (GF_FILEEXISTS(dirname) != 0 && ACE_OS::mkdir(dirname) != 0) {
    std::string msg =
        "Error in creating directories for: " + std::string(dirname);
    throw GeodeIOException(msg.c_str());
  }
  // retry some number of times before giving up when file is busy etc.
  int maxTries = 10;
  while (maxTries-- > 0) {
    g_log = fopen(g_logFileWithExt->c_str(), "a");
    if (g_log != nullptr) {
      break;
    }
    int lastError = ACE_OS::last_error();
    if (lastError != EACCES && lastError != EINTR && lastError != EWOULDBLOCK) {
      break;
    }
    // continue after some sleep
    std::this_thread::sleep_for(std::chrono::milliseconds(200));
  }
  if (!g_log) {
    g_isLogFileOpened = false;
    return;
  } else {
    g_isLogFileOpened = true;
  }

  if (s_logLevel == LogLevel::None) {
    return;
  }
  std::string bannertext = geodeBanner::getBanner();

  if (g_logFile == nullptr) {
    fprintf(stdout, "%s", bannertext.c_str());
    fflush(stdout);
    return;
  }  // else
  GF_D_ASSERT(g_logFile && g_logMutex && g_logFileWithExt);

  if (fprintf(g_log, "%s", bannertext.c_str()) == 0 || ferror(g_log)) {
    // we should be continue,
    return;
  }

  int numchars = 0;
  const char* pch = nullptr;
  pch = strchr(bannertext.c_str(), '\n');
  while (pch != nullptr) {
    pch = strchr(pch + 1, '\n');
    numchars += 2;
  }

  g_bytesWritten += static_cast<int32_t>(bannertext.length() + numchars);
  fflush(g_log);
}

const char* Log::levelToChars(LogLevel level) {
  switch (level) {
    case LogLevel::None:
      return "none";

    case LogLevel::Error:
      return "error";

    case LogLevel::Warning:
      return "warning";

    case LogLevel::Info:
      return "info";

    case LogLevel::Default:
      return "default";

    case LogLevel::Config:
      return "config";

    case LogLevel::Fine:
      return "fine";

    case LogLevel::Finer:
      return "finer";

    case LogLevel::Finest:
      return "finest";

    case LogLevel::Debug:
      return "debug";

    case LogLevel::All:
      return "all";

    default: {
      char buf[64] = {0};
      ACE_OS::snprintf(buf, 64, "Unexpected log level: %d",
                       static_cast<int>(level));
      throw IllegalArgumentException(buf);
    }
  }
}

LogLevel Log::charsToLevel(const std::string& chars) {
  std::string level = chars;

  if (level.empty()) return LogLevel::None;

  std::transform(level.begin(), level.end(), level.begin(), ::tolower);

  if (level == "none") {
    return LogLevel::None;
  } else if (level == "error") {
    return LogLevel::Error;
  } else if (level == "warning") {
    return LogLevel::Warning;
  } else if (level == "info") {
    return LogLevel::Info;
  } else if (level == "default") {
    return LogLevel::Default;
  } else if (level == "config") {
    return LogLevel::Config;
  } else if (level == "fine") {
    return LogLevel::Fine;
  } else if (level == "finer") {
    return LogLevel::Finer;
  } else if (level == "finest") {
    return LogLevel::Finest;
  } else if (level == "debug") {
    return LogLevel::Debug;
  } else if (level == "all") {
    return LogLevel::All;
  } else {
    throw IllegalArgumentException(("Unexpected log level: " + level).c_str());
  }
}

char* Log::formatLogLine(char* buf, LogLevel level) {
  if (g_pid == 0) {
    g_pid = ACE_OS::getpid();
    ACE_OS::uname(&g_uname);
  }
  const size_t MINBUFSIZE = 128;
  ACE_Time_Value clock = ACE_OS::gettimeofday();
  time_t secs = clock.sec();
  struct tm* tm_val = ACE_OS::localtime(&secs);
  char* pbuf = buf;
  pbuf += ACE_OS::snprintf(pbuf, 15, "[%s ", Log::levelToChars(level));
  pbuf += ACE_OS::strftime(pbuf, MINBUFSIZE, "%Y/%m/%d %H:%M:%S", tm_val);
  pbuf +=
      ACE_OS::snprintf(pbuf, 15, ".%06ld ", static_cast<long>(clock.usec()));
  pbuf += ACE_OS::strftime(pbuf, MINBUFSIZE, "%Z ", tm_val);

  ACE_OS::snprintf(pbuf, 300, "%s:%d %lu] ", g_uname.nodename, g_pid,
                   (unsigned long)ACE_OS::thr_self());

  return buf;
}

void Log::put(LogLevel level, const std::string& msg) {
  put(level, msg.c_str());
}

// int g_count = 0;
void Log::put(LogLevel level, const char* msg) {
  ACE_Guard<ACE_Thread_Mutex> guard(*g_logMutex);

  g_fileInfo fileInfo;

  char buf[256] = {0};
  char fullpath[512] = {0};

  if (!g_logFile) {
    fprintf(stdout, "%s%s\n", formatLogLine(buf, level), msg);
    fflush(stdout);
    // TODO: ignoring for now; probably store the log-lines for possible
    // future logging if log-file gets initialized properly

  } else {
    if (!g_isLogFileOpened) {
      g_log = fopen(g_logFileWithExt->c_str(), "a");
      if (!g_log) {
        g_isLogFileOpened = false;
        return;
      }
      g_isLogFileOpened = true;
    } else if (!g_log) {
      g_log = fopen(g_logFileWithExt->c_str(), "a");
      if (!g_log) {
        return;
      }
    }

    formatLogLine(buf, level);
    size_t numChars =
        static_cast<int>(ACE_OS::strlen(buf) + ACE_OS::strlen(msg));
    g_bytesWritten +=
        numChars + 2;  // bcoz we have to count trailing new line (\n)

    if ((g_fileSizeLimit != 0) && (g_bytesWritten >= g_fileSizeLimit)) {
      char rollFile[1024] = {0};
      std::string logsdirname;
      std::string logsbasename;
      std::string fnameBeforeExt;
      std::string extName;
      std::string newfilestr;

      int32_t len = static_cast<int32_t>(g_logFileWithExt->length());
      int32_t lastPosOfSep = static_cast<int32_t>(
          g_logFileWithExt->find_last_of(ACE_DIRECTORY_SEPARATOR_CHAR, len));
      if (lastPosOfSep == -1) {
        logsdirname = ".";
      } else {
        logsdirname = g_logFileWithExt->substr(0, lastPosOfSep);
      }
      logsbasename = g_logFileWithExt->substr(lastPosOfSep + 1, len);
      char logFileExtAfter = '.';
      int32_t baselen = static_cast<int32_t>(logsbasename.length());
      int32_t posOfExt = static_cast<int32_t>(
          logsbasename.find_last_of(logFileExtAfter, baselen));
      if (posOfExt == -1) {
        // throw IllegalArgument;
      } else {
        fnameBeforeExt = logsbasename.substr(0, posOfExt);
        extName = logsbasename.substr(posOfExt + 1, baselen);
      }
      ACE_OS::snprintf(rollFile, 1024, "%s%c%s-%d.%s", logsdirname.c_str(),
                       ACE_DIRECTORY_SEPARATOR_CHAR, fnameBeforeExt.c_str(),
                       g_rollIndex++, extName.c_str());
      bool rollFileNameGot = false;
      while (!rollFileNameGot) {
        FILE* fp1 = fopen(rollFile, "r");
        if (fp1 != nullptr) {
          fclose(fp1);
          ACE_OS::snprintf(rollFile, 1024, "%s%c%s-%d.%s", logsdirname.c_str(),
                           ACE_DIRECTORY_SEPARATOR_CHAR, fnameBeforeExt.c_str(),
                           g_rollIndex++, extName.c_str());
        } else {
          rollFileNameGot = true;
        }
      }

      fclose(g_log);
      g_log = nullptr;

      if (ACE_OS::rename(g_logFileWithExt->c_str(), rollFile) < 0) {
        return;  // no need to throw exception try next time
      }

      g_bytesWritten =
          numChars + 2;  // bcoz we have to count trailing new line (\n)
      writeBanner();
    }

    g_spaceUsed += g_bytesWritten;

    if ((g_diskSpaceLimit > 0) && (g_spaceUsed >= g_diskSpaceLimit)) {
      std::string dirname = ACE::dirname(g_logFile->c_str());
      g_spaceUsed = 0;
      ACE_stat statBuf = {};

      ACE_Dirent_Selector sds;
      int status = sds.open(dirname.c_str(), selector, comparator);
      if (status != -1) {
        for (int index = 1; index < sds.length(); ++index) {
          ACE_OS::snprintf(fullpath, 512, "%s%c%s", dirname.c_str(),
                           ACE_DIRECTORY_SEPARATOR_CHAR, sds[index]->d_name);
          ACE_OS::stat(fullpath, &statBuf);
          g_fileInfoPair = std::make_pair(fullpath, statBuf.st_size);
          fileInfo.push_back(g_fileInfoPair);
          g_spaceUsed += fileInfo[index - 1].second;
        }  // for loop
        g_spaceUsed += g_bytesWritten;
        sds.close();
      }
      int fileIndex = 0;

      while ((g_spaceUsed > (g_diskSpaceLimit /*- g_fileSizeLimit*/))) {
        int64_t fileSize = fileInfo[fileIndex].second;
        if (ACE_OS::unlink(fileInfo[fileIndex].first.c_str()) == 0) {
          g_spaceUsed -= fileSize;
        } else {
          char printmsg[256];
          ACE_OS::snprintf(printmsg, 256, "%s\t%s\n", "Could not delete",
                           fileInfo[fileIndex].first.c_str());
          int numChars =
              fprintf(g_log, "%s%s\n", formatLogLine(buf, level), printmsg);
          g_bytesWritten +=
              numChars + 2;  // bcoz we have to count trailing new line (\n)
        }
        fileIndex++;
      }
    }

    if ((numChars = fprintf(g_log, "%s%s\n", buf, msg)) == 0 || ferror(g_log)) {
      if ((g_diskSpaceLimit > 0)) {
        g_spaceUsed = g_spaceUsed - (numChars + 2);
      }
      if (g_fileSizeLimit > 0) {
        g_bytesWritten = g_bytesWritten - (numChars + 2);
      }

      // lets continue wothout throwing the exception; it should not cause
      // process to terminate
      fclose(g_log);
      g_log = nullptr;
    } else {
      fflush(g_log);
    }
  }
}

void Log::putThrow(LogLevel level, const char* msg, const Exception& ex) {
  std::string message = "Geode exception " + ex.getName() +
                        " thrown: " + ex.getMessage() + "\n" + msg;
  put(level, message);
}

void Log::putCatch(LogLevel level, const char* msg, const Exception& ex) {
  std::string message = "Geode exception " + ex.getName() +
                        " caught: " + ex.getMessage() + "\n" + msg;
  put(level, message);
}

void Log::enterFn(LogLevel level, const char* functionName) {
  enum { MAX_NAME_LENGTH = 1024 };
  std::string fn = functionName;
  if (fn.size() > MAX_NAME_LENGTH) {
    fn = fn.substr(fn.size() - MAX_NAME_LENGTH, MAX_NAME_LENGTH);
  }
  char buf[MAX_NAME_LENGTH + 512] = {0};
  ACE_OS::snprintf(buf, 1536, "{{{===>>> Entering function %s", fn.c_str());
  put(level, buf);
}

void Log::exitFn(LogLevel level, const char* functionName) {
  enum { MAX_NAME_LENGTH = 1024 };
  std::string fn = functionName;
  if (fn.size() > MAX_NAME_LENGTH) {
    fn = fn.substr(fn.size() - MAX_NAME_LENGTH, MAX_NAME_LENGTH);
  }
  char buf[MAX_NAME_LENGTH + 512] = {0};
  ACE_OS::snprintf(buf, 1536, "<<<===}}} Exiting function %s", fn.c_str());
  put(level, buf);
}

// var arg logging routines.

#ifdef _WIN32
#define vsnprintf _vsnprintf
#endif

void LogVarargs::debug(const char* fmt, ...) {
  char msg[_GF_MSG_LIMIT] = {0};
  va_list argp;
  va_start(argp, fmt);
  vsnprintf(msg, _GF_MSG_LIMIT, fmt, argp);
  /* win doesn't guarantee termination */ msg[_GF_MSG_LIMIT - 1] = '\0';
  Log::put(LogLevel::Debug, msg);
  va_end(argp);
}

void LogVarargs::error(const char* fmt, ...) {
  char msg[_GF_MSG_LIMIT] = {0};
  va_list argp;
  va_start(argp, fmt);
  vsnprintf(msg, _GF_MSG_LIMIT, fmt, argp);
  /* win doesn't guarantee termination */ msg[_GF_MSG_LIMIT - 1] = '\0';
  Log::put(LogLevel::Error, msg);
  va_end(argp);
}

void LogVarargs::warn(const char* fmt, ...) {
  char msg[_GF_MSG_LIMIT] = {0};
  va_list argp;
  va_start(argp, fmt);
  vsnprintf(msg, _GF_MSG_LIMIT, fmt, argp);
  /* win doesn't guarantee termination */ msg[_GF_MSG_LIMIT - 1] = '\0';
  Log::put(LogLevel::Warning, msg);
  va_end(argp);
}

void LogVarargs::info(const char* fmt, ...) {
  char msg[_GF_MSG_LIMIT] = {0};
  va_list argp;
  va_start(argp, fmt);
  vsnprintf(msg, _GF_MSG_LIMIT, fmt, argp);
  /* win doesn't guarantee termination */ msg[_GF_MSG_LIMIT - 1] = '\0';
  Log::put(LogLevel::Info, msg);
  va_end(argp);
}

void LogVarargs::config(const char* fmt, ...) {
  char msg[_GF_MSG_LIMIT] = {0};
  va_list argp;
  va_start(argp, fmt);
  vsnprintf(msg, _GF_MSG_LIMIT, fmt, argp);
  /* win doesn't guarantee termination */ msg[_GF_MSG_LIMIT - 1] = '\0';
  Log::put(LogLevel::Config, msg);
  va_end(argp);
}

void LogVarargs::fine(const char* fmt, ...) {
  char msg[_GF_MSG_LIMIT] = {0};
  va_list argp;
  va_start(argp, fmt);
  vsnprintf(msg, _GF_MSG_LIMIT, fmt, argp);
  /* win doesn't guarantee termination */ msg[_GF_MSG_LIMIT - 1] = '\0';
  Log::put(LogLevel::Fine, msg);
  va_end(argp);
}

void LogVarargs::finer(const char* fmt, ...) {
  char msg[_GF_MSG_LIMIT] = {0};
  va_list argp;
  va_start(argp, fmt);
  vsnprintf(msg, _GF_MSG_LIMIT, fmt, argp);
  /* win doesn't guarantee termination */ msg[_GF_MSG_LIMIT - 1] = '\0';
  Log::put(LogLevel::Finer, msg);
  va_end(argp);
}

void LogVarargs::finest(const char* fmt, ...) {
  char msg[_GF_MSG_LIMIT] = {0};
  va_list argp;
  va_start(argp, fmt);
  vsnprintf(msg, _GF_MSG_LIMIT, fmt, argp);
  /* win doesn't guarantee termination */ msg[_GF_MSG_LIMIT - 1] = '\0';
  Log::put(LogLevel::Finest, msg);
  va_end(argp);
}

}  // namespace client
}  // namespace geode
}  // namespace apache
