/*
 * Copyright 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "repeating_timer.h"

#include "message_loop_thread.h"
#include "time_util.h"

#include <base/functional/callback.h>
#include <base/logging.h>

namespace bluetooth {

namespace common {

constexpr std::chrono::microseconds kMinimumPeriod =
    std::chrono::microseconds(1);

// This runs on user thread
RepeatingTimer::~RepeatingTimer() {
  std::lock_guard<std::recursive_mutex> api_lock(api_mutex_);
  if (message_loop_thread_ != nullptr && message_loop_thread_->IsRunning()) {
    CancelAndWait();
  }
}

// This runs on user thread
bool RepeatingTimer::SchedulePeriodic(
    const base::WeakPtr<MessageLoopThread>& thread,
    const base::Location& from_here, base::RepeatingClosure task,
    std::chrono::microseconds period) {
  if (period < kMinimumPeriod) {
    LOG(ERROR) << __func__ << ": period must be at least "
               << kMinimumPeriod.count();
    return false;
  }

  uint64_t time_now_us = time_get_os_boottime_us();
  uint64_t time_next_task_us = time_now_us + period.count();
  std::lock_guard<std::recursive_mutex> api_lock(api_mutex_);
  if (thread == nullptr) {
    LOG(ERROR) << __func__ << ": thread must be non-null";
    return false;
  }
  CancelAndWait();
  expected_time_next_task_us_ = time_next_task_us;
  task_ = std::move(task);
  task_wrapper_.Reset(
      base::Bind(&RepeatingTimer::RunTask, base::Unretained(this)));
  message_loop_thread_ = thread;
  period_ = period;
  uint64_t time_until_next_us = time_next_task_us - time_get_os_boottime_us();
  if (!thread->DoInThreadDelayed(
          from_here, task_wrapper_.callback(),
          std::chrono::microseconds(time_until_next_us))) {
    LOG(ERROR) << __func__
               << ": failed to post task to message loop for thread " << *thread
               << ", from " << from_here.ToString();
    expected_time_next_task_us_ = 0;
    task_wrapper_.Cancel();
    message_loop_thread_ = nullptr;
    period_ = {};
    return false;
  }
  return true;
}

// This runs on user thread
void RepeatingTimer::Cancel() {
  std::promise<void> promise;
  CancelHelper(std::move(promise));
}

// This runs on user thread
void RepeatingTimer::CancelAndWait() {
  std::promise<void> promise;
  auto future = promise.get_future();
  CancelHelper(std::move(promise));
  future.wait();
}

// This runs on user thread
void RepeatingTimer::CancelHelper(std::promise<void> promise) {
  std::lock_guard<std::recursive_mutex> api_lock(api_mutex_);
  MessageLoopThread* scheduled_thread = message_loop_thread_.get();
  if (scheduled_thread == nullptr) {
    promise.set_value();
    return;
  }
  if (scheduled_thread->GetThreadId() == base::PlatformThread::CurrentId()) {
    CancelClosure(std::move(promise));
    return;
  }
  scheduled_thread->DoInThread(
      FROM_HERE, base::BindOnce(&RepeatingTimer::CancelClosure,
                                base::Unretained(this), std::move(promise)));
}

// This runs on message loop thread
void RepeatingTimer::CancelClosure(std::promise<void> promise) {
  message_loop_thread_ = nullptr;
  task_wrapper_.Cancel();
#if BASE_VER < 927031
  task_ = {};
#else
  task_ = base::NullCallback();
#endif
  period_ = std::chrono::microseconds(0);
  expected_time_next_task_us_ = 0;
  promise.set_value();
}

// This runs on user thread
bool RepeatingTimer::IsScheduled() const {
  std::lock_guard<std::recursive_mutex> api_lock(api_mutex_);
  return message_loop_thread_ != nullptr && message_loop_thread_->IsRunning();
}

// This runs on message loop thread
void RepeatingTimer::RunTask() {
  if (message_loop_thread_ == nullptr || !message_loop_thread_->IsRunning()) {
    LOG(ERROR) << __func__
               << ": message_loop_thread_ is null or is not running";
    return;
  }
  CHECK_EQ(message_loop_thread_->GetThreadId(),
           base::PlatformThread::CurrentId())
      << ": task must run on message loop thread";

  int64_t period_us = period_.count();
  expected_time_next_task_us_ += period_us;
  uint64_t time_now_us = time_get_os_boottime_us();
  int64_t remaining_time_us = expected_time_next_task_us_ - time_now_us;
  if (remaining_time_us < 0) {
    // if remaining_time_us is negative, schedule the task to the nearest
    // multiple of period
    remaining_time_us = (remaining_time_us % period_us + period_us) % period_us;
  }
  message_loop_thread_->DoInThreadDelayed(
      FROM_HERE, task_wrapper_.callback(),
      std::chrono::microseconds(remaining_time_us));

  uint64_t time_before_task_us = time_get_os_boottime_us();
  task_.Run();
  uint64_t time_after_task_us = time_get_os_boottime_us();
  auto task_time_us =
      static_cast<int64_t>(time_after_task_us - time_before_task_us);
  if (task_time_us > period_.count()) {
    LOG(ERROR) << __func__ << ": Periodic task execution took " << task_time_us
               << " microseconds, longer than interval " << period_.count()
               << " microseconds";
  }
}

}  // namespace common

}  // namespace bluetooth
