/*
 * 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 "util/Log.hpp"

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

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

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

#include "../internal/hacks/AceThreadId.h"
#include "Assert.hpp"
#include "geodeBanner.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, ".%06" PRId64 " ",
                           static_cast<int64_t>(clock.usec()));
  pbuf += ACE_OS::strftime(pbuf, MINBUFSIZE, "%Z ", tm_val);

  ACE_OS::snprintf(pbuf, 300, "%s:%d %" PRIu64 "] ", g_uname.nodename, g_pid,
                   hacks::aceThreadId(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
