/*
 *  Copyright 2006 The WebRTC Project Authors. All rights reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

// Most of this was borrowed (with minor modifications) from V8's and Chromium's
// src/base/logging.cc.

#include <stdlib.h>
#include <cstdarg>
#include <cstdio>
#include <cstdlib>
#include <string>

#include "absl/strings/string_view.h"

#if defined(WEBRTC_ANDROID)
#define RTC_LOG_TAG_ANDROID "rtc"
#include <android/log.h>  // NOLINT
#endif

#if defined(WEBRTC_WIN)
#include <windows.h>
#endif

#if defined(WEBRTC_WIN)
#define LAST_SYSTEM_ERROR (::GetLastError())
#elif defined(WEBRTC_POSIX)
#include <cerrno>
#define LAST_SYSTEM_ERROR (errno)
#endif  // WEBRTC_WIN

#include "rtc_base/checks.h"

namespace webrtc {

namespace {

#if defined(__GNUC__)
__attribute__((__format__(__printf__, 2, 3)))
#endif
void AppendFormat(std::string* s, const char* fmt, ...) {
  va_list args, copy;
  va_start(args, fmt);
  va_copy(copy, args);
  const int predicted_length = std::vsnprintf(nullptr, 0, fmt, copy);
  va_end(copy);

  if (predicted_length > 0) {
    const size_t size = s->size();
    s->resize(size + predicted_length);
    // Pass "+ 1" to vsnprintf to include space for the '\0'.
    std::vsnprintf(&((*s)[size]), predicted_length + 1, fmt, args);
  }
  va_end(args);
}
}  // namespace

namespace webrtc_checks_impl {

#if !defined(WEBRTC_CHROMIUM_BUILD)
RTC_NORETURN void WriteFatalLog(absl::string_view output) {
#if defined(WEBRTC_ANDROID)
  std::string output_str(output);
  __android_log_print(ANDROID_LOG_ERROR, RTC_LOG_TAG_ANDROID, "%s\n",
                      output_str.c_str());
#endif
  fflush(stdout);
  fwrite(output.data(), output.size(), 1, stderr);
  fflush(stderr);
#if defined(WEBRTC_WIN)
  DebugBreak();
#endif
  abort();
}

RTC_NORETURN void WriteFatalLog(const char* /* file */,
                                int /* line */,
                                absl::string_view output) {
  WriteFatalLog(output);
}

#endif  // !defined(WEBRTC_CHROMIUM_BUILD)

#if RTC_CHECK_MSG_ENABLED
// Reads one argument from args, appends it to s and advances fmt.
// Returns true iff an argument was sucessfully parsed.
bool ParseArg(va_list* args, const CheckArgType** fmt, std::string* s) {
  if (**fmt == CheckArgType::kEnd)
    return false;

  switch (**fmt) {
    case CheckArgType::kInt:
      AppendFormat(s, "%d", va_arg(*args, int));
      break;
    case CheckArgType::kLong:
      AppendFormat(s, "%ld", va_arg(*args, long));
      break;
    case CheckArgType::kLongLong:
      AppendFormat(s, "%lld", va_arg(*args, long long));
      break;
    case CheckArgType::kUInt:
      AppendFormat(s, "%u", va_arg(*args, unsigned));
      break;
    case CheckArgType::kULong:
      AppendFormat(s, "%lu", va_arg(*args, unsigned long));
      break;
    case CheckArgType::kULongLong:
      AppendFormat(s, "%llu", va_arg(*args, unsigned long long));
      break;
    case CheckArgType::kDouble:
      AppendFormat(s, "%g", va_arg(*args, double));
      break;
    case CheckArgType::kLongDouble:
      AppendFormat(s, "%Lg", va_arg(*args, long double));
      break;
    case CheckArgType::kCharP:
      s->append(va_arg(*args, const char*));
      break;
    case CheckArgType::kStdString:
      s->append(*va_arg(*args, const std::string*));
      break;
    case CheckArgType::kStringView: {
      const absl::string_view sv = *va_arg(*args, const absl::string_view*);
      s->append(sv.data(), sv.size());
      break;
    }
    case CheckArgType::kVoidP:
      AppendFormat(s, "%p", va_arg(*args, const void*));
      break;
    default:
      s->append("[Invalid CheckArgType]");
      return false;
  }
  (*fmt)++;
  return true;
}

RTC_NORETURN void FatalLog(const char* file,
                           int line,
                           const char* message,
                           const CheckArgType* fmt,
                           ...) {
  va_list args;
  va_start(args, fmt);

  std::string s;
  AppendFormat(&s,
               "\n\n"
               "#\n"
               "# Fatal error in: %s, line %d\n"
               "# last system error: %u\n"
               "# Check failed: %s",
               file, line, LAST_SYSTEM_ERROR, message);

  if (*fmt == CheckArgType::kCheckOp) {
    // This log message was generated by RTC_CHECK_OP, so we have to complete
    // the error message using the operands that have been passed as the first
    // two arguments.
    fmt++;

    std::string s1, s2;
    if (ParseArg(&args, &fmt, &s1) && ParseArg(&args, &fmt, &s2))
      AppendFormat(&s, " (%s vs. %s)\n# ", s1.c_str(), s2.c_str());
  } else {
    s.append("\n# ");
  }

  // Append all the user-supplied arguments to the message.
  while (ParseArg(&args, &fmt, &s))
    ;

  va_end(args);

  WriteFatalLog(file, line, s);
}
#else  // RTC_CHECK_MSG_ENABLED
RTC_NORETURN void FatalLog(const char* file, int line) {
  std::string s;
  AppendFormat(&s,
               "\n\n"
               "#\n"
               "# Fatal error in: %s, line %d\n"
               "# last system error: %u\n"
               "# Check failed.\n"
               "# ",
               file, line, LAST_SYSTEM_ERROR);
  WriteFatalLog(file, line, s);
}
#endif  // RTC_CHECK_MSG_ENABLED

#if RTC_DCHECK_IS_ON

RTC_NORETURN void UnreachableCodeReached(const char* file, int line) {
  std::string s;
  AppendFormat(&s,
               "\n\n"
               "#\n"
               "# Unreachable code reached: %s, line %d\n"
               "# last system error: %u\n"
               "# ",
               file, line, LAST_SYSTEM_ERROR);
  WriteFatalLog(file, line, s);
}

#else  // !RTC_DCHECK_IS_ON

RTC_NORETURN void UnreachableCodeReached() {
  std::string s;
  AppendFormat(&s,
               "\n\n"
               "#\n"
               "# Unreachable code reached (file and line unknown)\n"
               "# last system error: %u\n"
               "# ",
               LAST_SYSTEM_ERROR);
  WriteFatalLog(s);
}

#endif  // !RTC_DCHECK_IS_ON

}  // namespace webrtc_checks_impl
}  // namespace webrtc

// Function to call from the C version of the RTC_CHECK and RTC_DCHECK macros.
RTC_NORETURN void rtc_FatalMessage(const char* file,
                                   int line,
                                   const char* msg) {
#if RTC_CHECK_MSG_ENABLED
  static constexpr webrtc::webrtc_checks_impl::CheckArgType t[] = {
      webrtc::webrtc_checks_impl::CheckArgType::kEnd};
  webrtc::webrtc_checks_impl::FatalLog(file, line, msg, t);
#else
  webrtc::webrtc_checks_impl::FatalLog(file, line);
#endif
}
