/*
 *  Copyright (c) 2011 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 "system_wrappers/source/event_timer_posix.h"

#if defined(WEBRTC_ANDROID)
#include <android/api-level.h>
#endif

#include <errno.h>
#include <pthread.h>
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <sys/time.h>
#include <unistd.h>

#include "rtc_base/checks.h"

#if defined(HAVE_PTHREAD_COND_TIMEDWAIT_MONOTONIC)
// Chromium build is always defining this macro if __ANDROID_API__ < 20.
#undef HAVE_PTHREAD_COND_TIMEDWAIT_MONOTONIC
#endif

#if defined(WEBRTC_ANDROID) && defined(__ANDROID_API__)
#define HAVE_PTHREAD_COND_TIMEDWAIT_MONOTONIC (__ANDROID_API__ < 21)
#else
#define HAVE_PTHREAD_COND_TIMEDWAIT_MONOTONIC 0
#endif

namespace webrtc {

// static
EventTimerWrapper* EventTimerWrapper::Create() {
  return new EventTimerPosix();
}

const int64_t kNanosecondsPerMillisecond = 1000000;
const int64_t kNanosecondsPerSecond = 1000000000;

EventTimerPosix::EventTimerPosix()
    : event_set_(false),
      timer_thread_(nullptr),
      created_at_(),
      periodic_(false),
      time_ms_(0),
      count_(0),
      is_stopping_(false) {
  pthread_mutexattr_t attr;
  pthread_mutexattr_init(&attr);
  pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
  pthread_mutex_init(&mutex_, &attr);
  pthread_condattr_t cond_attr;
  pthread_condattr_init(&cond_attr);
// TODO(sprang): Remove HAVE_PTHREAD_COND_TIMEDWAIT_MONOTONIC special case once
// all supported Android platforms support pthread_condattr_setclock.
// TODO(sprang): Add support for monotonic clock on Apple platforms.
#if !(defined(WEBRTC_MAC) || defined(WEBRTC_IOS)) && \
    !(defined(WEBRTC_ANDROID) && HAVE_PTHREAD_COND_TIMEDWAIT_MONOTONIC)
  pthread_condattr_setclock(&cond_attr, CLOCK_MONOTONIC);
#endif
  pthread_cond_init(&cond_, &cond_attr);
  pthread_condattr_destroy(&cond_attr);
}

EventTimerPosix::~EventTimerPosix() {
  StopTimer();
  pthread_cond_destroy(&cond_);
  pthread_mutex_destroy(&mutex_);
}

// TODO(pbos): Make this void.
bool EventTimerPosix::Set() {
  RTC_CHECK_EQ(0, pthread_mutex_lock(&mutex_));
  event_set_ = true;
  pthread_cond_signal(&cond_);
  pthread_mutex_unlock(&mutex_);
  return true;
}

EventTypeWrapper EventTimerPosix::Wait(unsigned long timeout_ms) {
  int ret_val = 0;
  RTC_CHECK_EQ(0, pthread_mutex_lock(&mutex_));

  if (!event_set_) {
    if (WEBRTC_EVENT_INFINITE != timeout_ms) {
      timespec end_at;
#ifndef WEBRTC_MAC
      clock_gettime(CLOCK_MONOTONIC, &end_at);
#else
      timeval value;
      struct timezone time_zone;
      time_zone.tz_minuteswest = 0;
      time_zone.tz_dsttime = 0;
      gettimeofday(&value, &time_zone);
      TIMEVAL_TO_TIMESPEC(&value, &end_at);
#endif
      end_at.tv_sec += timeout_ms / 1000;
      end_at.tv_nsec += (timeout_ms % 1000) * kNanosecondsPerMillisecond;

      if (end_at.tv_nsec >= kNanosecondsPerSecond) {
        end_at.tv_sec++;
        end_at.tv_nsec -= kNanosecondsPerSecond;
      }
      while (ret_val == 0 && !event_set_) {
#if defined(WEBRTC_ANDROID) && HAVE_PTHREAD_COND_TIMEDWAIT_MONOTONIC
        ret_val = pthread_cond_timedwait_monotonic_np(&cond_, &mutex_, &end_at);
#else
        ret_val = pthread_cond_timedwait(&cond_, &mutex_, &end_at);
#endif  // WEBRTC_ANDROID && HAVE_PTHREAD_COND_TIMEDWAIT_MONOTONIC
      }
    } else {
      while (ret_val == 0 && !event_set_)
        ret_val = pthread_cond_wait(&cond_, &mutex_);
    }
  }

  RTC_DCHECK(ret_val == 0 || ret_val == ETIMEDOUT);

  // Reset and signal if set, regardless of why the thread woke up.
  if (event_set_) {
    ret_val = 0;
    event_set_ = false;
  }
  pthread_mutex_unlock(&mutex_);

  return ret_val == 0 ? kEventSignaled : kEventTimeout;
}

EventTypeWrapper EventTimerPosix::Wait(timespec* end_at, bool reset_event) {
  int ret_val = 0;
  RTC_CHECK_EQ(0, pthread_mutex_lock(&mutex_));
  if (reset_event) {
    // Only wake for new events or timeouts.
    event_set_ = false;
  }

  while (ret_val == 0 && !event_set_) {
#if defined(WEBRTC_ANDROID) && HAVE_PTHREAD_COND_TIMEDWAIT_MONOTONIC
    ret_val = pthread_cond_timedwait_monotonic_np(&cond_, &mutex_, end_at);
#else
    ret_val = pthread_cond_timedwait(&cond_, &mutex_, end_at);
#endif  // WEBRTC_ANDROID && HAVE_PTHREAD_COND_TIMEDWAIT_MONOTONIC
  }

  RTC_DCHECK(ret_val == 0 || ret_val == ETIMEDOUT);

  // Reset and signal if set, regardless of why the thread woke up.
  if (event_set_) {
    ret_val = 0;
    event_set_ = false;
  }
  pthread_mutex_unlock(&mutex_);

  return ret_val == 0 ? kEventSignaled : kEventTimeout;
}

rtc::PlatformThread* EventTimerPosix::CreateThread() {
  const char* kThreadName = "WebRtc_event_timer_thread";
  return new rtc::PlatformThread(Run, this, kThreadName);
}

bool EventTimerPosix::StartTimer(bool periodic, unsigned long time_ms) {
  pthread_mutex_lock(&mutex_);
  if (timer_thread_) {
    if (periodic_) {
      // Timer already started.
      pthread_mutex_unlock(&mutex_);
      return false;
    } else {
      // New one shot timer.
      time_ms_ = time_ms;
      created_at_.tv_sec = 0;
      timer_event_->Set();
      pthread_mutex_unlock(&mutex_);
      return true;
    }
  }

  // Start the timer thread.
  timer_event_.reset(new EventTimerPosix());
  timer_thread_.reset(CreateThread());
  periodic_ = periodic;
  time_ms_ = time_ms;
  timer_thread_->Start();
  timer_thread_->SetPriority(rtc::kRealtimePriority);
  pthread_mutex_unlock(&mutex_);

  return true;
}

bool EventTimerPosix::Run(void* obj) {
  return static_cast<EventTimerPosix*>(obj)->Process();
}

bool EventTimerPosix::Process() {
  pthread_mutex_lock(&mutex_);
  if (is_stopping_) {
    pthread_mutex_unlock(&mutex_);
    return false;
  }
  if (created_at_.tv_sec == 0) {
#ifndef WEBRTC_MAC
    RTC_CHECK_EQ(0, clock_gettime(CLOCK_MONOTONIC, &created_at_));
#else
    timeval value;
    struct timezone time_zone;
    time_zone.tz_minuteswest = 0;
    time_zone.tz_dsttime = 0;
    gettimeofday(&value, &time_zone);
    TIMEVAL_TO_TIMESPEC(&value, &created_at_);
#endif
    count_ = 0;
  }

  timespec end_at;
  unsigned long long total_delta_ms = time_ms_ * ++count_;
  if (!periodic_ && count_ >= 1) {
    // No need to wake up often if we're not going to signal waiting threads.
    total_delta_ms =
        std::min<uint64_t>(total_delta_ms, 60 * kNanosecondsPerSecond);
  }

  end_at.tv_sec = created_at_.tv_sec + total_delta_ms / 1000;
  end_at.tv_nsec = created_at_.tv_nsec +
                   (total_delta_ms % 1000) * kNanosecondsPerMillisecond;

  if (end_at.tv_nsec >= kNanosecondsPerSecond) {
    end_at.tv_sec++;
    end_at.tv_nsec -= kNanosecondsPerSecond;
  }

  pthread_mutex_unlock(&mutex_);
  // Reset event on first call so that we don't immediately return here if this
  // thread was not blocked on timer_event_->Wait when the StartTimer() call
  // was made.
  if (timer_event_->Wait(&end_at, count_ == 1) == kEventSignaled)
    return true;

  pthread_mutex_lock(&mutex_);
  if (periodic_ || count_ == 1)
    Set();
  pthread_mutex_unlock(&mutex_);

  return true;
}

bool EventTimerPosix::StopTimer() {
  pthread_mutex_lock(&mutex_);
  is_stopping_ = true;
  pthread_mutex_unlock(&mutex_);

  if (timer_event_)
    timer_event_->Set();

  if (timer_thread_) {
    timer_thread_->Stop();
    timer_thread_.reset();
  }
  timer_event_.reset();

  // Set time to zero to force new reference time for the timer.
  memset(&created_at_, 0, sizeof(created_at_));
  count_ = 0;
  return true;
}

}  // namespace webrtc
