/*
 * 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 <future>
#include <memory>
#include <thread>

#include "benchmark/benchmark.h"
#include "common/bind.h"
#include "os/handler.h"
#include "os/thread.h"

using ::benchmark::State;
using ::bluetooth::common::BindOnce;
using ::bluetooth::os::Handler;
using ::bluetooth::os::Thread;

#define NUM_MESSAGES_TO_SEND 100000

class BM_ThreadPerformance : public ::benchmark::Fixture {
 protected:
  void SetUp(State& st) override {
    benchmark::Fixture::SetUp(st);
    counter_promise_ = std::promise<void>();
    counter_ = 0;
  }
  void TearDown(State& st) override {
    benchmark::Fixture::TearDown(st);
  }
  void callback_batch() {
    counter_++;
    if (counter_ >= num_messages_to_send_) {
      counter_promise_.set_value();
    }
  }

  void callback() {
    counter_promise_.set_value();
  }

  int64_t num_messages_to_send_;
  int64_t counter_;
  std::promise<void> counter_promise_;
};

class BM_ReactorThread : public BM_ThreadPerformance {
 protected:
  void SetUp(State& st) override {
    BM_ThreadPerformance::SetUp(st);
    thread_ = std::make_unique<Thread>("BM_ReactorThread thread", Thread::Priority::NORMAL);
    handler_ = std::make_unique<Handler>(thread_.get());
  }
  void TearDown(State& st) override {
    handler_ = nullptr;
    thread_->Stop();
    thread_ = nullptr;
    BM_ThreadPerformance::TearDown(st);
  }
  std::unique_ptr<Thread> thread_;
  std::unique_ptr<Handler> handler_;
};

BENCHMARK_DEFINE_F(BM_ReactorThread, batch_enque_dequeue)(State& state) {
  for (auto _ : state) {
    num_messages_to_send_ = state.range(0);
    counter_ = 0;
    counter_promise_ = std::promise<void>();
    std::future<void> counter_future = counter_promise_.get_future();
    for (int i = 0; i < num_messages_to_send_; i++) {
      handler_->Post(BindOnce(
          &BM_ReactorThread_batch_enque_dequeue_Benchmark::callback_batch, bluetooth::common::Unretained(this)));
    }
    counter_future.wait();
  }
};

BENCHMARK_REGISTER_F(BM_ReactorThread, batch_enque_dequeue)
    ->Arg(10)
    ->Arg(1000)
    ->Arg(10000)
    ->Arg(100000)
    ->Iterations(1)
    ->UseRealTime();

BENCHMARK_DEFINE_F(BM_ReactorThread, sequential_execution)(State& state) {
  for (auto _ : state) {
    num_messages_to_send_ = state.range(0);
    for (int i = 0; i < num_messages_to_send_; i++) {
      counter_promise_ = std::promise<void>();
      std::future<void> counter_future = counter_promise_.get_future();
      handler_->Post(
          BindOnce(&BM_ReactorThread_sequential_execution_Benchmark::callback, bluetooth::common::Unretained(this)));
      counter_future.wait();
    }
  }
};

BENCHMARK_REGISTER_F(BM_ReactorThread, sequential_execution)
    ->Arg(10)
    ->Arg(1000)
    ->Arg(10000)
    ->Arg(100000)
    ->Iterations(1)
    ->UseRealTime();
