/*
 *  Copyright 2007 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.
 */
//
// A reuseable entry point for gunit tests.

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

#include "rtc_base/flags.h"
#include "rtc_base/logging.h"
#include "rtc_base/ssl_adapter.h"
#include "rtc_base/ssl_stream_adapter.h"
#include "rtc_base/thread.h"
#include "system_wrappers/include/field_trial.h"
#include "system_wrappers/include/metrics.h"
#include "test/field_trial.h"
#include "test/gtest.h"

#if defined(WEBRTC_WIN)
#include "rtc_base/win32_socket_init.h"
#endif

#if defined(WEBRTC_IOS)
#include "test/ios/test_support.h"
#endif

WEBRTC_DEFINE_bool(help, false, "prints this message");
WEBRTC_DEFINE_string(log, "", "logging options to use");
WEBRTC_DEFINE_string(
    force_fieldtrials,
    "",
    "Field trials control experimental feature code which can be forced. "
    "E.g. running with --force_fieldtrials=WebRTC-FooFeature/Enable/"
    " will assign the group Enable to field trial WebRTC-FooFeature.");
#if defined(WEBRTC_WIN)
WEBRTC_DEFINE_int(crt_break_alloc, -1, "memory allocation to break on");
WEBRTC_DEFINE_bool(
    default_error_handlers,
    false,
    "leave the default exception/dbg handler functions in place");

void TestInvalidParameterHandler(const wchar_t* expression,
                                 const wchar_t* function,
                                 const wchar_t* file,
                                 unsigned int line,
                                 uintptr_t pReserved) {
  // In order to log `expression`, `function`, and `file` here, we would have
  // to convert them to const char*. std::wcsrtombs can do that, but it's
  // locale dependent.
  RTC_LOG(LS_ERROR) << "InvalidParameter Handler called.  Exiting.";
  exit(1);
}
void TestPureCallHandler() {
  RTC_LOG(LS_ERROR) << "Purecall Handler called.  Exiting.";
  exit(1);
}
int TestCrtReportHandler(int report_type, char* msg, int* retval) {
  RTC_LOG(LS_ERROR) << "CrtReport Handler called...";
  RTC_LOG(LS_ERROR) << msg;
  if (report_type == _CRT_ASSERT) {
    exit(1);
  } else {
    *retval = 0;
    return TRUE;
  }
}
#endif  // WEBRTC_WIN

int main(int argc, char* argv[]) {
  ::testing::InitGoogleTest(&argc, argv);
  rtc::FlagList::SetFlagsFromCommandLine(&argc, argv, false);
  if (FLAG_help) {
    rtc::FlagList::Print(nullptr, false);
    return 0;
  }

  webrtc::test::ValidateFieldTrialsStringOrDie(FLAG_force_fieldtrials);
  // InitFieldTrialsFromString stores the char*, so the char array must outlive
  // the application.
  webrtc::field_trial::InitFieldTrialsFromString(FLAG_force_fieldtrials);
  webrtc::metrics::Enable();

#if defined(WEBRTC_WIN)
  rtc::WinsockInitializer winsock_init;

  if (!FLAG_default_error_handlers) {
    // Make sure any errors don't throw dialogs hanging the test run.
    _set_invalid_parameter_handler(TestInvalidParameterHandler);
    _set_purecall_handler(TestPureCallHandler);
    _CrtSetReportHook2(_CRT_RPTHOOK_INSTALL, TestCrtReportHandler);
  }

#if !defined(NDEBUG)  // Turn on memory leak checking on Windows.
  _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
  if (FLAG_crt_break_alloc >= 0) {
    _crtBreakAlloc = FLAG_crt_break_alloc;
  }
#endif
#endif  // WEBRTC_WIN

  // By default, log timestamps. Allow overrides by used of a --log flag.
  rtc::LogMessage::LogTimestamps();
  if (*FLAG_log != '\0') {
    rtc::LogMessage::ConfigureLogging(FLAG_log);
  } else if (rtc::LogMessage::GetLogToDebug() > rtc::LS_INFO) {
    // Default to LS_INFO, even for release builds to provide better test
    // logging.
    rtc::LogMessage::LogToDebug(rtc::LS_INFO);
  }

  // Initialize SSL which are used by several tests.
  rtc::InitializeSSL();
  rtc::SSLStreamAdapter::EnableTimeCallbackForTesting();

#if defined(WEBRTC_IOS)
  rtc::test::InitTestSuite(RUN_ALL_TESTS, argc, argv, false);
  rtc::test::RunTestsFromIOSApp();
#endif

  rtc::AutoThread main_thread;
  const int res = RUN_ALL_TESTS();

  rtc::CleanupSSL();

  // clean up logging so we don't appear to leak memory.
  rtc::LogMessage::ConfigureLogging("");

#if defined(WEBRTC_WIN)
  // Unhook crt function so that we don't ever log after statics have been
  // uninitialized.
  if (!FLAG_default_error_handlers)
    _CrtSetReportHook2(_CRT_RPTHOOK_REMOVE, TestCrtReportHandler);
#endif

#if defined(ADDRESS_SANITIZER) || defined(LEAK_SANITIZER) ||  \
    defined(MEMORY_SANITIZER) || defined(THREAD_SANITIZER) || \
    defined(UNDEFINED_SANITIZER)
  // We want the test flagged as failed only for sanitizer defects,
  // in which case the sanitizer will override exit code with 66.
  return 0;
#endif

  return res;
}
