/*
 * Copyright 2019 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_alarm.h"

#include <future>

#include "base/logging.h"
#include "gtest/gtest.h"

namespace bluetooth {
namespace common {
namespace {

constexpr int error_ms = 20;

class RepeatingAlarmTest : public ::testing::Test {
 protected:
  void SetUp() override {
    thread_ = new Thread("test_thread", Thread::Priority::NORMAL);
    alarm_ = new RepeatingAlarm(thread_);
  }

  void TearDown() override {
    delete alarm_;
    delete thread_;
  }

  void VerifyMultipleDelayedTasks(int scheduled_tasks, int task_length_ms, int interval_between_tasks_ms) {
    std::promise<void> promise;
    auto future = promise.get_future();
    auto start_time = std::chrono::steady_clock::now();
    int counter = 0;
    alarm_->Schedule(
        [&counter, &promise, start_time, scheduled_tasks, task_length_ms, interval_between_tasks_ms]() {
          counter++;
          auto time_now = std::chrono::steady_clock::now();
          auto time_delta = time_now - start_time;
          if (counter == scheduled_tasks) {
            promise.set_value();
          }
          ASSERT_NEAR(time_delta.count(), interval_between_tasks_ms * 1000000 * counter, error_ms * 1000000);
          std::this_thread::sleep_for(std::chrono::milliseconds(task_length_ms));
        },
        std::chrono::milliseconds(interval_between_tasks_ms));
    future.get();
    alarm_->Cancel();
  }

  RepeatingAlarm* alarm_;

 private:
  Thread* thread_;
};

TEST_F(RepeatingAlarmTest, cancel_while_not_armed) {
  alarm_->Cancel();
}

TEST_F(RepeatingAlarmTest, schedule) {
  std::promise<void> promise;
  auto future = promise.get_future();
  auto before = std::chrono::steady_clock::now();
  int period_ms = 10;
  alarm_->Schedule([&promise]() { promise.set_value(); }, std::chrono::milliseconds(period_ms));
  future.get();
  alarm_->Cancel();
  auto after = std::chrono::steady_clock::now();
  auto duration = after - before;
  ASSERT_NEAR(duration.count(), period_ms * 1000000, error_ms * 1000000);
}

TEST_F(RepeatingAlarmTest, cancel_alarm) {
  alarm_->Schedule([]() { LOG(FATAL) << "Should not happen"; }, std::chrono::milliseconds(1));
  alarm_->Cancel();
  std::this_thread::sleep_for(std::chrono::milliseconds(5));
}

TEST_F(RepeatingAlarmTest, cancel_alarm_from_callback) {
  alarm_->Schedule([this]() { this->alarm_->Cancel(); }, std::chrono::milliseconds(1));
  std::this_thread::sleep_for(std::chrono::milliseconds(5));
}

TEST_F(RepeatingAlarmTest, schedule_while_alarm_armed) {
  alarm_->Schedule([]() { LOG(FATAL) << "Should not happen"; }, std::chrono::milliseconds(1));
  std::promise<void> promise;
  auto future = promise.get_future();
  alarm_->Schedule([&promise]() { promise.set_value(); }, std::chrono::milliseconds(10));
  future.get();
  alarm_->Cancel();
}

TEST_F(RepeatingAlarmTest, delete_while_alarm_armed) {
  alarm_->Schedule([]() { LOG(FATAL) << "Should not happen"; }, std::chrono::milliseconds(1));
  delete alarm_;
  alarm_ = nullptr;
  std::this_thread::sleep_for(std::chrono::milliseconds(1));
}

TEST_F(RepeatingAlarmTest, verify_small) {
  VerifyMultipleDelayedTasks(100, 1, 10);
}

TEST_F(RepeatingAlarmTest, verify_large) {
  VerifyMultipleDelayedTasks(100, 3, 10);
}

}  // namespace
}  // namespace common
}  // namespace bluetooth
