/*
 * 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.
 */

#pragma once

#ifndef GEODE_LOG_H_
#define GEODE_LOG_H_

#include <cstdarg>
#include <cstdio>
#include <string>

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

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

#ifndef GEODE_HIGHEST_LOG_LEVEL
#define GEODE_HIGHEST_LOG_LEVEL LogLevel::All
#endif

#ifndef GEODE_MAX_LOG_FILE_LIMIT
#define GEODE_MAX_LOG_FILE_LIMIT (1024 * 1024 * 1024)
#endif

#ifndef GEODE_MAX_LOG_DISK_LIMIT
#define GEODE_MAX_LOG_DISK_LIMIT (1024ll * 1024ll * 1024ll * 1024ll)
#endif

#define _GEODE_LOG_MESSAGE_LIMIT 8192

namespace apache {
namespace geode {
namespace client {

class Exception;

/** Defines methods available to clients that want to write a log message
 * to their Geode system's shared log file.
 * <p>
 * This class must be initialized prior to its use:
 * @ref Log::init
 * <p>
 * For any logged message the log file will contain:
 * <ul>
 * <li> The message's level.
 * <li> The time the message was logged.
 * <li> The id of the connection and thread that logged the message.
 * <li> The message itself which can be a const char* (perhaps with
 * an exception including the exception's stack trace.
 * </ul>
 * <p>
 * A message always has a level.
 * Logging levels are ordered. Enabling logging at a given level also
 * enables logging at higher levels. The higher the level the more
 * important and urgent the message.
 * <p>
 * The levels, in descending order of severity, are:
 * <ul>
 *
 * <li> <code>error</code> (highest severity) is a message level
 * indicating a serious failure.  In general <code>error</code>
 * messages should describe events that are of considerable
 * importance and which will prevent normal program execution. They
 * should be reasonably intelligible to end users and to system
 * administrators.
 *
 * <li> <code>warning</code> is a message level indicating a
 * potential problem.  In general <code>warning</code> messages
 * should describe events that will be of interest to end users or
 * system managers, or which indicate potential problems.
 *
 * <li> <code>info</code> is a message level for informational
 * messages.  Typically <code>info</code> messages should be
 * reasonably significant and should make sense to end users and
 * system administrators.
 *
 * <li> <code>config</code> is a message level for static
 * configuration messages.  <code>config</code> messages are intended
 * to provide a variety of static configuration information, to
 * assist in debugging problems that may be associated with
 * particular configurations.
 *
 * <li> <code>fine</code> is a message level providing tracing
 * information.  In general the <code>fine</code> level should be
 * used for information that will be broadly interesting to
 * developers. This level is for the lowest volume, and most
 * important, tracing messages.
 *
 * <li> <code>finer</code> indicates a moderately detailed tracing
 * message.  This is an intermediate level between <code>fine</code>
 * and <code>finest</code>.
 *
 * <li> <code>finest</code> indicates a very detailed tracing
 * message.  Logging calls for entering, returning, or throwing an
 * exception are traced at the <code>finest</code> level.
 *
 * <li> <code>debug</code> (lowest severity) indicates a highly
 * detailed tracing message.  In general the <code>debug</code> level
 * should be used for the most voluminous detailed tracing messages.
 * </ul>
 *
 * <p>
 * For each level methods exist that will request a message, at that
 * level, to be logged. These methods are all named after their level.
 * <p>
 * For each level a method exists that indicates if messages at that
 * level will currently be logged. The names of these methods are of
 * the form: <em>level</em><code>Enabled</code>.
 *
 *
 */

class APACHE_GEODE_EXPORT Log {
 public:
  /**
   * Returns the current log level.
   */
  static LogLevel logLevel();

  /**
   * Set the current log level.
   */
  static void setLogLevel(LogLevel level);

  /**
   * Initializes logging facility with given level and filenames.
   * This method is called automatically within @ref DistributedSystem::connect
   * with the log-file, log-level, and log-file-size system properties used as
   * arguments
   */
  static void init
      // 0 => use default value (currently 1GB for file, 1TB for disk)
      (LogLevel level, const char* logFileName, int32_t logFileLimit = 0,
       int64_t logDiskSpaceLimit = 0);

  static void init(LogLevel level, const std::string& logFileName,
                   int32_t logFileLimit = 0, int64_t logDiskSpaceLimit = 0);

  /**
   * closes logging facility (until next init).
   */
  static void close();

  /**
   * returns character string for given log level. The string will be
   * identical to the enum declaration above, except it will be all
   * lower case. Out of range values will throw
   * IllegalArgumentException.
   */
  static const char* levelToChars(LogLevel level);

  /**
   * returns log level specified by "chars", or throws
   * IllegalArgumentException.  Allowed values are identical to the
   * enum declaration above for LogLevel, but with character case ignored.
   */
  static LogLevel charsToLevel(const std::string& chars);

  /**
   * formats and returns a line for logging.
   *
   * This is provided so that applications wishing to use the same format
   * as Geode log-lines can do so easily. A log-line starts with the prefix
   * given below which is filled in by this method:
   * [<level> <date> <time> <timezone> <host>:<process ID> <thread ID>]
   *
   * This method is not thread-safe for the first invocation.
   * When invoking from outside either <init> should have been invoked,
   * or at least the first invocation should be single-threaded.
   */
  static std::string formatLogLine(LogLevel level);

  static void log(LogLevel level, const std::string& msg);

  static void log(LogLevel level, const char* fmt, ...);

  static void logCatch(LogLevel level, const char* msg, const Exception& ex);

  static bool enabled(LogLevel level);

 private:
  static LogLevel s_logLevel;

  static void writeBanner();

  static void validateSizeLimits(int64_t fileSizeLimit, int64_t diskSpaceLimit);

  static void validateLogFileName(const std::string& filename);

  static void rollLogFile();

  static void removeOldestRolledLogFile();

  static void buildRollFileMapping();

  static void setRollFileIndex();

  static void setSizeLimits(int32_t logFileLimit, int64_t logDiskSpaceLimit);

  static void logInternal(LogLevel level, const std::string& msg);

  static void calculateUsedDiskSpace();
};

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

#define LOGERROR(...)                                             \
  do {                                                            \
    if (::apache::geode::client::Log::enabled(                    \
            apache::geode::client::LogLevel::Error)) {            \
      ::apache::geode::client::Log::log(                          \
          ::apache::geode::client::LogLevel::Error, __VA_ARGS__); \
    }                                                             \
  } while (false)

#define LOGWARN(...)                                                \
  do {                                                              \
    if (::apache::geode::client::Log::enabled(                      \
            apache::geode::client::LogLevel::Warning)) {            \
      ::apache::geode::client::Log::log(                            \
          ::apache::geode::client::LogLevel::Warning, __VA_ARGS__); \
    }                                                               \
  } while (false)

#define LOGINFO(...)                                             \
  do {                                                           \
    if (::apache::geode::client::Log::enabled(                   \
            apache::geode::client::LogLevel::Info)) {            \
      ::apache::geode::client::Log::log(                         \
          ::apache::geode::client::LogLevel::Info, __VA_ARGS__); \
    }                                                            \
  } while (false)

#define LOGCONFIG(...)                                             \
  do {                                                             \
    if (::apache::geode::client::Log::enabled(                     \
            apache::geode::client::LogLevel::Config)) {            \
      ::apache::geode::client::Log::log(                           \
          ::apache::geode::client::LogLevel::Config, __VA_ARGS__); \
    }                                                              \
  } while (false)

#define LOGFINE(...)                                             \
  do {                                                           \
    if (::apache::geode::client::Log::enabled(                   \
            apache::geode::client::LogLevel::Fine)) {            \
      ::apache::geode::client::Log::log(                         \
          ::apache::geode::client::LogLevel::Fine, __VA_ARGS__); \
    }                                                            \
  } while (false)

#define LOGFINER(...)                                             \
  do {                                                            \
    if (::apache::geode::client::Log::enabled(                    \
            apache::geode::client::LogLevel::Finer)) {            \
      ::apache::geode::client::Log::log(                          \
          ::apache::geode::client::LogLevel::Finer, __VA_ARGS__); \
    }                                                             \
  } while (false)

#define LOGFINEST(...)                                             \
  do {                                                             \
    if (::apache::geode::client::Log::enabled(                     \
            apache::geode::client::LogLevel::Finest)) {            \
      ::apache::geode::client::Log::log(                           \
          ::apache::geode::client::LogLevel::Finest, __VA_ARGS__); \
    }                                                              \
  } while (false)

#define LOGDEBUG(...)                                             \
  do {                                                            \
    if (::apache::geode::client::Log::enabled(                    \
            apache::geode::client::LogLevel::Debug)) {            \
      ::apache::geode::client::Log::log(                          \
          ::apache::geode::client::LogLevel::Debug, __VA_ARGS__); \
    }                                                             \
  } while (false)

#endif  // GEODE_LOG_H_
