/*
 * 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 <algorithm>
#include <cctype>
#include <chrono>
#include <cstdio>
#include <ctime>
#include <map>
#include <mutex>
#include <regex>
#include <sstream>
#include <string>
#include <thread>
#include <utility>

#include <boost/asio/ip/host_name.hpp>
#include <boost/filesystem.hpp>
#include <boost/process/environment.hpp>

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

#include "geodeBanner.hpp"
#include "util/chrono/time_point.hpp"

namespace {

static size_t g_bytesWritten = 0;

static size_t g_fileSizeLimit = GEODE_MAX_LOG_FILE_LIMIT;
static size_t g_diskSpaceLimit = GEODE_MAX_LOG_DISK_LIMIT;

static std::mutex g_logMutex;

static int g_rollIndex = 0;
static size_t g_spaceUsed = 0;

static boost::filesystem::path g_fullpath;
static std::map<int32_t, boost::filesystem::path> g_rollFiles;

static FILE* g_log = nullptr;

static std::string g_hostName;

const int __1K__ = 1024;
const int __1M__ = (__1K__ * __1K__);

}  // namespace

namespace apache {
namespace geode {
namespace client {

LogLevel Log::s_logLevel = LogLevel::Default;

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

LogLevel Log::logLevel() { return s_logLevel; }

/**
 * Set the current log level.
 */
void Log::setLogLevel(LogLevel level) { s_logLevel = level; }

void Log::validateSizeLimits(int64_t fileSizeLimit, int64_t diskSpaceLimit) {
  if (fileSizeLimit * __1M__ > GEODE_MAX_LOG_FILE_LIMIT) {
    throw IllegalArgumentException(
        "Specified file size limit larger than max allowed (1GB)");
  } else if (fileSizeLimit < 0) {
    throw IllegalArgumentException("Specified file size limit must be >= 0");
  }

  if (diskSpaceLimit * __1M__ > GEODE_MAX_LOG_DISK_LIMIT) {
    throw IllegalArgumentException(
        "Specified disk space limit larger than max allowed (1TB)");
  } else if (diskSpaceLimit < 0) {
    throw IllegalArgumentException("Specified disk space limit must be >= 0");
  }

  if (fileSizeLimit > diskSpaceLimit && diskSpaceLimit != 0) {
    throw IllegalArgumentException(
        "Disk space limit must be larger than file size limit");
  }
}

void Log::init(LogLevel level, const char* logFileName, int32_t logFileLimit,
               int64_t logDiskSpaceLimit) {
  auto logFileNameString =
      logFileName ? std::string(logFileName) : std::string("geode-native.log");
  init(level, logFileNameString, logFileLimit, logDiskSpaceLimit);
}

void Log::rollLogFile() {
  if (g_log) {
    fclose(g_log);
    g_log = nullptr;
  }

  auto rollFileName =
      (g_fullpath.parent_path() /
       (g_fullpath.stem().string() + "-" + std::to_string(g_rollIndex) +
        g_fullpath.extension().string()))
          .string();
  try {
    auto rollFile = boost::filesystem::path(rollFileName);
    boost::filesystem::rename(g_fullpath, rollFile);
    g_rollFiles[g_rollIndex] = rollFile;
    g_rollIndex++;
  } catch (const boost::filesystem::filesystem_error&) {
    throw IllegalStateException("Failed to roll log file");
  }
}

void Log::removeOldestRolledLogFile() {
  if (g_rollFiles.size()) {
    auto index = g_rollFiles.begin()->first;
    auto fileToRemove = g_rollFiles.begin()->second;
    auto fileSize = boost::filesystem::file_size(fileToRemove);
    boost::filesystem::remove(fileToRemove);
    g_rollFiles.erase(index);
    g_spaceUsed -= fileSize;
  } else {
    throw IllegalStateException(
        "Failed to free sufficient disk space for logs");
  }
}

void Log::calculateUsedDiskSpace() {
  g_spaceUsed = 0;
  if (boost::filesystem::exists(g_fullpath)) {
    g_spaceUsed = boost::filesystem::file_size(g_fullpath);
    for (auto const& item : g_rollFiles) {
      g_spaceUsed += boost::filesystem::file_size(item.second);
    }
  }
}

void Log::buildRollFileMapping() {
  const auto filterstring = g_fullpath.stem().string() + "-(\\d+)\\.log$";
  const std::regex my_filter(filterstring);

  g_rollFiles.clear();

  boost::filesystem::directory_iterator end_itr;
  for (boost::filesystem::directory_iterator i(
           g_fullpath.parent_path().string());
       i != end_itr; ++i) {
    if (boost::filesystem::is_regular_file(i->status())) {
      std::string filename = i->path().filename().string();
      std::regex testPattern(filterstring);
      std::match_results<std::string::const_iterator> testMatches;
      if (std::regex_search(std::string::const_iterator(filename.begin()),
                            filename.cend(), testMatches, testPattern)) {
        auto index = std::atoi(
            std::string(testMatches[1].first, testMatches[1].second).c_str());
        g_rollFiles[index] = i->path();
      }
    }
  }
}

void Log::setRollFileIndex() {
  g_rollIndex = 0;
  if (g_rollFiles.size()) {
    g_rollIndex = g_rollFiles.rbegin()->first + 1;
  }
}

void Log::setSizeLimits(int32_t logFileLimit, int64_t logDiskSpaceLimit) {
  validateSizeLimits(logFileLimit, logDiskSpaceLimit);

  // Default to 10MB file limit and 1GB disk limit
  if (logFileLimit == 0 && logDiskSpaceLimit == 0) {
    g_fileSizeLimit = 10 * __1M__;
    g_diskSpaceLimit = 1000 * __1M__;
  }
  // disk space specified but file size is defaulted.  Just use a single
  // log file, i.e. set file limit == disk limit
  else if (logFileLimit == 0) {
    g_diskSpaceLimit = logDiskSpaceLimit * __1M__;
    g_fileSizeLimit = g_diskSpaceLimit;
  } else if (logDiskSpaceLimit == 0) {
    g_fileSizeLimit = logFileLimit * __1M__;
    g_diskSpaceLimit = g_fileSizeLimit;
  } else {
    g_fileSizeLimit = logFileLimit * __1M__;
    g_diskSpaceLimit = logDiskSpaceLimit * __1M__;
  }
}

void Log::init(LogLevel level, const std::string& 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;

  try {
    std::lock_guard<decltype(g_logMutex)> guard(g_logMutex);

    g_hostName = boost::asio::ip::host_name();

    g_fullpath =
        boost::filesystem::absolute(boost::filesystem::path(logFileName));

    // if no extension then add .log extension
    if (g_fullpath.extension().empty() || (g_fullpath.extension() != ".log")) {
      g_fullpath = g_fullpath.string() + ".log";
    }

    setSizeLimits(logFileLimit, logDiskSpaceLimit);

    g_bytesWritten = 0;
    g_spaceUsed = 0;

    // Ensure that directory exists for log files.  We're going to attempt
    // to iterate through files in that folder, and if it doesn't exist boost
    // will throw an exception.
    const auto target_path = g_fullpath.parent_path().string();
    if (!boost::filesystem::exists(target_path)) {
      boost::filesystem::create_directories(target_path);
    }

    buildRollFileMapping();
    setRollFileIndex();
    calculateUsedDiskSpace();
    while (g_spaceUsed > g_diskSpaceLimit) {
      removeOldestRolledLogFile();
    }

    if (boost::filesystem::exists(g_fullpath) && logFileLimit > 0) {
      rollLogFile();
    }
    writeBanner();
  } catch (const boost::exception&) {
    auto msg = std::string("Unable to log to file '") + logFileName + "'";
    throw IllegalArgumentException(msg.c_str());
  } catch (const std::exception& ex) {
    auto msg = std::string("Unable to log to file '") + logFileName +
               "': " + ex.what();
    throw IllegalArgumentException(msg.c_str());
  }
}

void Log::close() {
  std::lock_guard<decltype(g_logMutex)> guard(g_logMutex);

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

void Log::writeBanner() {
  if (s_logLevel != LogLevel::None) {
    std::string bannertext = geodeBanner::getBanner();

    // fullpath empty --> we're logging to stdout
    if (g_fullpath.string().empty()) {
      fprintf(stdout, "%s", bannertext.c_str());
      fflush(stdout);
    } else {
      if (boost::filesystem::exists(
              g_fullpath.parent_path().string().c_str()) ||
          boost::filesystem::create_directories(g_fullpath.parent_path())) {
        g_log = fopen(g_fullpath.string().c_str(), "a");
        if (g_log) {
          if (fprintf(g_log, "%s", bannertext.c_str())) {
            g_bytesWritten += static_cast<int32_t>(bannertext.length());
            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";
  }
  throw IllegalArgumentException(std::string("Unexpected log level: ") +
                                 std::to_string(static_cast<int>(level)));
}

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());
  }
}

std::string Log::formatLogLine(LogLevel level) {
  std::stringstream msg;
  const size_t MINBUFSIZE = 128;
  auto now = std::chrono::system_clock::now();
  auto secs = std::chrono::system_clock::to_time_t(now);
  auto microseconds = std::chrono::duration_cast<std::chrono::microseconds>(
      now - std::chrono::system_clock::from_time_t(secs));
  auto tm_val = apache::geode::util::chrono::localtime(secs);

  msg << "[" << Log::levelToChars(level) << " "
      << std::put_time(&tm_val, "%Y/%m/%d %H:%M:%S") << '.' << std::setfill('0')
      << std::setw(6) << microseconds.count() << ' '
      << std::put_time(&tm_val, "%Z  ") << g_hostName << ":"
      << boost::this_process::get_id() << " " << std::this_thread::get_id()
      << "] ";

  return msg.str();
}

void Log::log(LogLevel level, const std::string& msg) {
  Log::logInternal(level, msg);
}

void Log::logInternal(LogLevel level, const std::string& msg) {
  std::lock_guard<decltype(g_logMutex)> guard(g_logMutex);

  std::string buf;
  char fullpath[512] = {0};

  if (g_fullpath.string().empty()) {
    fprintf(stdout, "%s%s\n", formatLogLine(level).c_str(), msg.c_str());
    fflush(stdout);
  } else {
    if (!g_log) {
      g_log = fopen(g_fullpath.string().c_str(), "a");
    }

    if (g_log) {
      buf = formatLogLine(level);
      auto numChars = static_cast<int>(buf.length() + msg.length());
      g_bytesWritten +=
          numChars + 2;  // bcoz we have to count trailing new line (\n)

      if ((g_fileSizeLimit != 0) && (g_bytesWritten >= g_fileSizeLimit)) {
        rollLogFile();
        g_bytesWritten = numChars + 2;  // Account for trailing newline
        writeBanner();
      }

      g_spaceUsed += numChars + 2;

      // Remove existing rolled log files until we're below the limit
      while (g_spaceUsed >= g_diskSpaceLimit) {
        removeOldestRolledLogFile();
      }

      if (fprintf(g_log, "%s%s\n", buf.c_str(), msg.c_str()) == 0 ||
          ferror(g_log)) {
        // Let's continue without throwing the exception.  It should not cause
        // process to terminate
        fclose(g_log);
        g_log = nullptr;
      } else {
        fflush(g_log);
      }
    }
  }
}

void Log::log(LogLevel level, const char* fmt, ...) {
  char msg[_GEODE_LOG_MESSAGE_LIMIT] = {0};
  va_list argp;
  va_start(argp, fmt);
  // NOLINTNEXTLINE(clang-analyzer-valist.Uninitialized): clang-tidy bug
  std::vsnprintf(msg, sizeof(msg), fmt, argp);
  Log::logInternal(level, std::string(msg));
  va_end(argp);
}

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

bool Log::enabled(LogLevel level) {
  return (level != LogLevel::None && level <= logLevel());
}

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