/*
 * 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 <chrono>
#include <future>
#include <unordered_map>

#include "benchmark/benchmark.h"

#include "common/bind.h"
#include "os/alarm.h"
#include "os/repeating_alarm.h"
#include "os/thread.h"

using ::benchmark::State;
using ::bluetooth::common::Bind;
using ::bluetooth::os::Alarm;
using ::bluetooth::os::Handler;
using ::bluetooth::os::RepeatingAlarm;
using ::bluetooth::os::Thread;

class BM_ReactableAlarm : public ::benchmark::Fixture {
 protected:
  void SetUp(State& st) override {
    ::benchmark::Fixture::SetUp(st);
    thread_ = std::make_unique<Thread>("timer_benchmark", Thread::Priority::REAL_TIME);
    handler_ = std::make_unique<Handler>(thread_.get());
    alarm_ = std::make_unique<Alarm>(handler_.get());
    repeating_alarm_ = std::make_unique<RepeatingAlarm>(handler_.get());
    map_.clear();
    scheduled_tasks_ = 0;
    task_length_ = 0;
    task_interval_ = 0;
    task_counter_ = 0;
    promise_ = std::promise<void>();
  }

  void TearDown(State& st) override {
    alarm_ = nullptr;
    repeating_alarm_ = nullptr;
    handler_ = nullptr;
    thread_->Stop();
    thread_ = nullptr;
    ::benchmark::Fixture::TearDown(st);
  }

  void AlarmSleepAndCountDelayedTime() {
    auto end_time = std::chrono::steady_clock::now();
    auto duration_since_start = std::chrono::duration_cast<std::chrono::milliseconds>(end_time - start_time_);
    task_counter_++;
    map_[duration_since_start.count() - task_counter_ * task_interval_]++;
    std::this_thread::sleep_for(std::chrono::milliseconds(task_length_));
    if (task_counter_ >= scheduled_tasks_) {
      promise_.set_value();
    }
  }

  void TimerFire() {
    promise_.set_value();
  }

  int64_t scheduled_tasks_;
  int64_t task_length_;
  int64_t task_interval_;
  int task_counter_;
  std::unordered_map<int, int> map_;
  std::promise<void> promise_;
  std::chrono::time_point<std::chrono::steady_clock> start_time_;
  std::unique_ptr<Thread> thread_;
  std::unique_ptr<Handler> handler_;
  std::unique_ptr<Alarm> alarm_;
  std::unique_ptr<RepeatingAlarm> repeating_alarm_;
};

BENCHMARK_DEFINE_F(BM_ReactableAlarm, timer_performance_ms)(State& state) {
  auto milliseconds = static_cast<int>(state.range(0));
  for (auto _ : state) {
    auto start_time_point = std::chrono::steady_clock::now();
    alarm_->Schedule(
        Bind(&BM_ReactableAlarm_timer_performance_ms_Benchmark::TimerFire, bluetooth::common::Unretained(this)),
        std::chrono::milliseconds(milliseconds));
    promise_.get_future().get();
    auto end_time_point = std::chrono::steady_clock::now();
    auto duration = std::chrono::duration_cast<std::chrono::nanoseconds>(end_time_point - start_time_point);
    state.SetIterationTime(static_cast<double>(duration.count()) * 1e-6);
    alarm_->Cancel();
  }
};

BENCHMARK_REGISTER_F(BM_ReactableAlarm, timer_performance_ms)
    ->Arg(1)
    ->Arg(5)
    ->Arg(10)
    ->Arg(20)
    ->Arg(100)
    ->Arg(1000)
    ->Arg(2000)
    ->Iterations(1)
    ->UseRealTime();

BENCHMARK_DEFINE_F(BM_ReactableAlarm, periodic_accuracy)(State& state) {
  for (auto _ : state) {
    scheduled_tasks_ = state.range(0);
    task_length_ = state.range(1);
    task_interval_ = state.range(2);
    start_time_ = std::chrono::steady_clock::now();
    repeating_alarm_->Schedule(Bind(&BM_ReactableAlarm_periodic_accuracy_Benchmark::AlarmSleepAndCountDelayedTime,
                                    bluetooth::common::Unretained(this)),
                               std::chrono::milliseconds(task_interval_));
    promise_.get_future().get();
    repeating_alarm_->Cancel();
  }
  for (const auto& delay : map_) {
    state.counters[std::to_string(delay.first)] = delay.second;
  }
};

BENCHMARK_REGISTER_F(BM_ReactableAlarm, periodic_accuracy)
    ->Args({2000, 1, 5})
    ->Args({2000, 3, 5})
    ->Args({2000, 1, 7})
    ->Args({2000, 3, 7})
    ->Args({2000, 1, 20})
    ->Args({2000, 5, 20})
    ->Args({2000, 10, 20})
    ->Args({2000, 15, 20})
    ->Iterations(1)
    ->UseRealTime();
