/** @file

  LogMessage implementation.

  @section license License

  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 "tscore/LogMessage.h"

#include "tscore/Diags.h"

using namespace std::chrono_literals;

std::atomic<std::chrono::milliseconds> LogMessage::_default_log_throttling_interval{0ms};
std::atomic<std::chrono::milliseconds> LogMessage::_default_debug_throttling_interval{0ms};

// static
void
LogMessage::set_default_log_throttling_interval(std::chrono::milliseconds new_interval)
{
  _default_log_throttling_interval = new_interval;
}

// static
void
LogMessage::set_default_debug_throttling_interval(std::chrono::milliseconds new_interval)
{
  _default_debug_throttling_interval = new_interval;
}

void
LogMessage::message_helper(std::chrono::microseconds current_configured_interval, log_function_f log_function, const char *fmt,
                           va_list args)
{
  if (!_is_throttled) {
    // If throttling is disabled, make this operation as efficient as possible.
    // Simply log and exit without consulting the Throttler API.
    //
    // If the user changes the throttling value from some non-zero value to
    // zero, then we may miss out on some "The following message was
    // suppressed" logs. However we accept this as a tradeoff to make this
    // common case as fast as possible.
    log_function(fmt, args);
    return;
  }
  if (!_throttling_value_is_explicitly_set) {
    set_throttling_interval(current_configured_interval);
  }
  uint64_t number_of_suppressions = 0;
  if (is_throttled(number_of_suppressions)) {
    // The messages are the same and but we're still within the throttling
    // interval. Suppress this message.
    return;
  }
  // If we get here, the message should not be suppressed.
  if (number_of_suppressions > 0) {
    // We use no format parameters, so we just need an empty va_list.
    va_list empty_args;
    std::string message =
      std::string("The following message was suppressed ") + std::to_string(number_of_suppressions) + std::string(" times.");
    log_function(message.c_str(), empty_args);
  }
  log_function(fmt, args);
}

void
LogMessage::standard_message_helper(DiagsLevel level, SourceLocation const &loc, const char *fmt, va_list args)
{
  message_helper(
    _default_log_throttling_interval.load(),
    [level, &loc](const char *fmt, va_list args) { diags->error_va(level, &loc, fmt, args); }, fmt, args);
}

void
LogMessage::message_debug_helper(const char *tag, DiagsLevel level, SourceLocation const &loc, const char *fmt, va_list args)
{
  message_helper(
    _default_debug_throttling_interval.load(),
    [tag, level, &loc](const char *fmt, va_list args) { diags->log_va(tag, level, &loc, fmt, args); }, fmt, args);
}

void
LogMessage::message_print_helper(const char *tag, DiagsLevel level, SourceLocation const &loc, const char *fmt, va_list args)
{
  message_helper(
    _default_debug_throttling_interval.load(),
    [tag, level, &loc](const char *fmt, va_list args) { diags->print_va(tag, level, &loc, fmt, args); }, fmt, args);
}

LogMessage::LogMessage(bool is_throttled)
  // Turn throttling off by default. Each log event will check the configured
  // throttling interval.
  : Throttler{std::chrono::milliseconds{0}}, _throttling_value_is_explicitly_set{false}, _is_throttled{is_throttled}
{
}

LogMessage::LogMessage(std::chrono::milliseconds throttling_interval)
  : Throttler{throttling_interval}, _throttling_value_is_explicitly_set{true}, _is_throttled{throttling_interval != 0ms}
{
}

void
LogMessage::diag(const char *tag, SourceLocation const &loc, const char *fmt, ...)
{
  va_list args;
  va_start(args, fmt);
  message_debug_helper(tag, DL_Diag, loc, fmt, args);
  va_end(args);
}

void
LogMessage::debug(const char *tag, SourceLocation const &loc, const char *fmt, ...)
{
  va_list args;
  va_start(args, fmt);
  message_debug_helper(tag, DL_Debug, loc, fmt, args);
  va_end(args);
}

void
LogMessage::status(SourceLocation const &loc, const char *fmt, ...)
{
  va_list args;
  va_start(args, fmt);
  standard_message_helper(DL_Status, loc, fmt, args);
  va_end(args);
}

void
LogMessage::note(SourceLocation const &loc, const char *fmt, ...)
{
  va_list args;
  va_start(args, fmt);
  standard_message_helper(DL_Note, loc, fmt, args);
  va_end(args);
}

void
LogMessage::warning(SourceLocation const &loc, const char *fmt, ...)
{
  va_list args;
  va_start(args, fmt);
  standard_message_helper(DL_Warning, loc, fmt, args);
  va_end(args);
}

void
LogMessage::error(SourceLocation const &loc, const char *fmt, ...)
{
  va_list args;
  va_start(args, fmt);
  standard_message_helper(DL_Error, loc, fmt, args);
  va_end(args);
}

void
LogMessage::fatal(SourceLocation const &loc, const char *fmt, ...)
{
  va_list args;
  va_start(args, fmt);
  standard_message_helper(DL_Fatal, loc, fmt, args);
  va_end(args);
}

void
LogMessage::alert(SourceLocation const &loc, const char *fmt, ...)
{
  va_list args;
  va_start(args, fmt);
  standard_message_helper(DL_Alert, loc, fmt, args);
  va_end(args);
}

void
LogMessage::emergency(SourceLocation const &loc, const char *fmt, ...)
{
  va_list args;
  va_start(args, fmt);
  standard_message_helper(DL_Emergency, loc, fmt, args);
  va_end(args);
}

void
LogMessage::message(DiagsLevel level, SourceLocation const &loc, const char *fmt, ...)
{
  va_list args;
  va_start(args, fmt);
  standard_message_helper(level, loc, fmt, args);
  va_end(args);
}

void
LogMessage::print(const char *tag, DiagsLevel level, SourceLocation const &loc, const char *fmt, ...)
{
  va_list args;
  va_start(args, fmt);
  message_print_helper(tag, level, loc, fmt, args);
  va_end(args);
}

void
LogMessage::diag_va(const char *tag, SourceLocation const &loc, const char *fmt, va_list args)
{
  message_debug_helper(tag, DL_Diag, loc, fmt, args);
}

void
LogMessage::debug_va(const char *tag, SourceLocation const &loc, const char *fmt, va_list args)
{
  message_debug_helper(tag, DL_Debug, loc, fmt, args);
}

void
LogMessage::status_va(SourceLocation const &loc, const char *fmt, va_list args)
{
  standard_message_helper(DL_Status, loc, fmt, args);
}

void
LogMessage::note_va(SourceLocation const &loc, const char *fmt, va_list args)
{
  standard_message_helper(DL_Note, loc, fmt, args);
}

void
LogMessage::warning_va(SourceLocation const &loc, const char *fmt, va_list args)
{
  standard_message_helper(DL_Warning, loc, fmt, args);
}

void
LogMessage::error_va(SourceLocation const &loc, const char *fmt, va_list args)
{
  standard_message_helper(DL_Error, loc, fmt, args);
}

void
LogMessage::fatal_va(SourceLocation const &loc, const char *fmt, va_list args)
{
  standard_message_helper(DL_Fatal, loc, fmt, args);
}

void
LogMessage::alert_va(SourceLocation const &loc, const char *fmt, va_list args)
{
  standard_message_helper(DL_Alert, loc, fmt, args);
}

void
LogMessage::emergency_va(SourceLocation const &loc, const char *fmt, va_list args)
{
  standard_message_helper(DL_Emergency, loc, fmt, args);
}

void
LogMessage::message_va(DiagsLevel level, SourceLocation const &loc, const char *fmt, va_list args)
{
  standard_message_helper(level, loc, fmt, args);
}
