/*
 *  Copyright (c) 2015 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.
 */

#include "rtc_base/platform_thread.h"

#include <algorithm>
#include <optional>
#include <string>
#include <utility>

#include "absl/functional/any_invocable.h"
#include "absl/strings/string_view.h"
#include "rtc_base/platform_thread_types.h"

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

#include "rtc_base/checks.h"

namespace webrtc {
namespace {

#if defined(WEBRTC_WIN)
int Win32PriorityFromThreadPriority(ThreadPriority priority) {
  switch (priority) {
    case ThreadPriority::kLow:
      return THREAD_PRIORITY_BELOW_NORMAL;
    case ThreadPriority::kNormal:
      return THREAD_PRIORITY_NORMAL;
    case ThreadPriority::kHigh:
    case ThreadPriority::kVideo:
      return THREAD_PRIORITY_ABOVE_NORMAL;
    case ThreadPriority::kAudio:
      return THREAD_PRIORITY_HIGHEST;
    case ThreadPriority::kRealtime:
      return THREAD_PRIORITY_TIME_CRITICAL;
  }
}
#endif

bool SetPriority(ThreadPriority priority) {
#if defined(WEBRTC_WIN)
  return SetThreadPriority(GetCurrentThread(),
                           Win32PriorityFromThreadPriority(priority)) != FALSE;
#elif defined(WEBRTC_FUCHSIA) || \
    (defined(__EMSCRIPTEN__) && !defined(__EMSCRIPTEN_PTHREADS__))
  // Setting thread priorities is not supported in NaCl, Fuchsia or Emscripten
  // without pthreads.
  return true;
#elif defined(WEBRTC_CHROMIUM_BUILD) && defined(WEBRTC_LINUX)
  // TODO(tommi): Switch to the same mechanism as Chromium uses for changing
  // thread priorities.
  return true;
#else
  const int policy = SCHED_FIFO;
  const int min_prio = sched_get_priority_min(policy);
  const int max_prio = sched_get_priority_max(policy);
  if (min_prio == -1 || max_prio == -1) {
    return false;
  }

  if (max_prio - min_prio <= 2)
    return false;

  // Convert webrtc priority to system priorities:
  sched_param param;
  const int top_prio = max_prio - 1;
  const int low_prio = min_prio + 1;
  switch (priority) {
    case ThreadPriority::kLow:
      param.sched_priority = low_prio;
      break;
    case ThreadPriority::kNormal:
      // The -1 ensures that the kHighPriority is always greater or equal to
      // kNormalPriority.
      param.sched_priority = (low_prio + top_prio - 1) / 2;
      break;
    case ThreadPriority::kHigh:
    case ThreadPriority::kVideo:
      param.sched_priority = std::max(top_prio - 2, low_prio);
      break;
    case ThreadPriority::kAudio:
      param.sched_priority = std::max(top_prio - 1, low_prio);
      break;
    case ThreadPriority::kRealtime:
      param.sched_priority = top_prio;
      break;
  }
  return pthread_setschedparam(pthread_self(), policy, &param) == 0;
#endif  // defined(WEBRTC_WIN)
}

#if defined(WEBRTC_WIN)
DWORD WINAPI RunPlatformThread(void* param) {
  // The GetLastError() function only returns valid results when it is called
  // after a Win32 API function that returns a "failed" result. A crash dump
  // contains the result from GetLastError() and to make sure it does not
  // falsely report a Windows error we call SetLastError here.
  ::SetLastError(ERROR_SUCCESS);
  auto function = static_cast<absl::AnyInvocable<void() &&>*>(param);
  std::move (*function)();
  delete function;
  return 0;
}
#else
void* RunPlatformThread(void* param) {
  auto function = static_cast<absl::AnyInvocable<void() &&>*>(param);
  std::move (*function)();
  delete function;
  return nullptr;
}
#endif  // defined(WEBRTC_WIN)

}  // namespace

PlatformThread::PlatformThread(Handle handle, bool joinable)
    : handle_(handle), joinable_(joinable) {}

PlatformThread::PlatformThread(PlatformThread&& rhs)
    : handle_(rhs.handle_), joinable_(rhs.joinable_) {
  rhs.handle_ = std::nullopt;
}

PlatformThread& PlatformThread::operator=(PlatformThread&& rhs) {
  Finalize();
  handle_ = rhs.handle_;
  joinable_ = rhs.joinable_;
  rhs.handle_ = std::nullopt;
  return *this;
}

PlatformThread::~PlatformThread() {
  Finalize();
}

PlatformThread PlatformThread::SpawnJoinable(
    absl::AnyInvocable<void() &&> thread_function,
    absl::string_view name,
    ThreadAttributes attributes) {
  return SpawnThread(std::move(thread_function), name, attributes,
                     /*joinable=*/true);
}

PlatformThread PlatformThread::SpawnDetached(
    absl::AnyInvocable<void() &&> thread_function,
    absl::string_view name,
    ThreadAttributes attributes) {
  return SpawnThread(std::move(thread_function), name, attributes,
                     /*joinable=*/false);
}

std::optional<PlatformThread::Handle> PlatformThread::GetHandle() const {
  return handle_;
}

#if defined(WEBRTC_WIN)
bool PlatformThread::QueueAPC(PAPCFUNC function, ULONG_PTR data) {
  RTC_DCHECK(handle_.has_value());
  return handle_.has_value() ? QueueUserAPC(function, *handle_, data) != FALSE
                             : false;
}
#endif

void PlatformThread::Finalize() {
  if (!handle_.has_value())
    return;
#if defined(WEBRTC_WIN)
  if (joinable_)
    WaitForSingleObject(*handle_, INFINITE);
  CloseHandle(*handle_);
#else
  if (joinable_)
    RTC_CHECK_EQ(0, pthread_join(*handle_, nullptr));
#endif
  handle_ = std::nullopt;
}

PlatformThread PlatformThread::SpawnThread(
    absl::AnyInvocable<void() &&> thread_function,
    absl::string_view name,
    ThreadAttributes attributes,
    bool joinable) {
  RTC_DCHECK(thread_function);
  RTC_DCHECK(!name.empty());
  // TODO(tommi): Consider lowering the limit to 15 (limit on Linux).
  RTC_DCHECK(name.length() < 64);
  auto start_thread_function_ptr = new absl::AnyInvocable<void() &&>(
      [thread_function = std::move(thread_function), name = std::string(name),
       attributes]() mutable {
        SetCurrentThreadName(name.c_str());
        SetPriority(attributes.priority);
        std::move(thread_function)();
      });
#if defined(WEBRTC_WIN)
  // See bug 2902 for background on STACK_SIZE_PARAM_IS_A_RESERVATION.
  // Set the reserved stack stack size to 1M, which is the default on Windows
  // and Linux.
  DWORD thread_id = 0;
  PlatformThread::Handle handle = ::CreateThread(
      nullptr, 1024 * 1024, &RunPlatformThread, start_thread_function_ptr,
      STACK_SIZE_PARAM_IS_A_RESERVATION, &thread_id);
  RTC_CHECK(handle) << "CreateThread failed";
#else
  pthread_attr_t attr;
  pthread_attr_init(&attr);
  // Set the stack stack size to 1M.
  pthread_attr_setstacksize(&attr, 1024 * 1024);
  pthread_attr_setdetachstate(
      &attr, joinable ? PTHREAD_CREATE_JOINABLE : PTHREAD_CREATE_DETACHED);
  PlatformThread::Handle handle;
  RTC_CHECK_EQ(0, pthread_create(&handle, &attr, &RunPlatformThread,
                                 start_thread_function_ptr));
  pthread_attr_destroy(&attr);
#endif  // defined(WEBRTC_WIN)
  return PlatformThread(handle, joinable);
}

}  // namespace webrtc
