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