#include "aos/logging/interface.h"

#include <stdarg.h>
#include <stdio.h>
#include <string.h>

#include <functional>
#include <type_traits>

#include "aos/die.h"
#include "aos/logging/context.h"

namespace aos {
namespace logging {
namespace internal {

size_t ExecuteFormat(char *output, size_t output_size, const char *format,
                     va_list ap) {
  static const char *const continued = "...\n";
  const size_t size = output_size - strlen(continued);
  const int ret = vsnprintf(output, size, format, ap);
  typedef ::std::common_type<int, size_t>::type RetType;
  if (ret < 0) {
    AOS_PLOG(FATAL, "vsnprintf(%p, %zd, %s, args) failed", output, size,
             format);
  } else if (static_cast<RetType>(ret) >= static_cast<RetType>(size)) {
    // Overwrite the '\0' at the end of the existing data and
    // copy in the one on the end of continued.
    memcpy(&output[size - 1], continued, strlen(continued) + 1);
  }
  return ::std::min<RetType>(ret, size);
}

void RunWithCurrentImplementation(
    ::std::function<void(LogImplementation *)> function) {
  Context *context = Context::Get();

  LogImplementation *const implementation = context->implementation;
  if (implementation == NULL) {
    Die("no logging implementation to use\n");
  }
  function(implementation);
}

}  // namespace internal

using internal::Context;

void LogImplementation::DoVLog(log_level level, const char *format,
                               va_list ap) {
  auto log_impl = [&](LogImplementation *implementation) {
    va_list ap1;
    va_copy(ap1, ap);
    implementation->DoLog(level, format, ap1);
    va_end(ap1);

    if (level == FATAL) {
      VDie(format, ap);
    }
  };
  internal::RunWithCurrentImplementation(::std::ref(log_impl));
}

void VLog(log_level level, const char *format, va_list ap) {
  LogImplementation::DoVLog(level, format, ap);
}

void VCork(int line, const char *function, const char *format, va_list ap) {
  Context *context = Context::Get();

  const size_t message_length = strlen(context->cork_data.message);
  if (line > context->cork_data.line_max) context->cork_data.line_max = line;
  if (line < context->cork_data.line_min) context->cork_data.line_min = line;

  if (context->cork_data.function == NULL) {
    context->cork_data.function = function;
  } else {
    if (strcmp(context->cork_data.function, function) != 0) {
      AOS_LOG(FATAL,
              "started corking data in function %s but then moved to %s\n",
              context->cork_data.function, function);
    }
  }

  internal::ExecuteFormat(context->cork_data.message + message_length,
                          sizeof(context->cork_data.message) - message_length,
                          format, ap);
}

void VUnCork(int line, const char *function, log_level level, const char *file,
             const char *format, va_list ap) {
  Context *context = Context::Get();

  VCork(line, function, format, ap);

  log_do(level, "%s: %d-%d: %s: %s", file, context->cork_data.line_min,
         context->cork_data.line_max, function, context->cork_data.message);

  context->cork_data.Reset();
}

}  // namespace logging
}  // namespace aos

void log_do(log_level level, const char *format, ...) {
  va_list ap;
  va_start(ap, format);
  aos::logging::VLog(level, format, ap);
  va_end(ap);
}

void log_cork(int line, const char *function, const char *format, ...) {
  va_list ap;
  va_start(ap, format);
  aos::logging::VCork(line, function, format, ap);
  va_end(ap);
}

void log_uncork(int line, const char *function, log_level level,
                const char *file, const char *format, ...) {
  va_list ap;
  va_start(ap, format);
  aos::logging::VUnCork(line, function, level, file, format, ap);
  va_end(ap);
}
