/*
 *  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"

#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"

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) &&                     \
      defined(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) && defined(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) && defined(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
