#include "benchmark_state.hpp"

#include <chrono>

#include "benchmark_config.hpp"
#include "utils/assert.hpp"

namespace hyrise {

BenchmarkState::BenchmarkState(const Duration init_max_duration) : max_duration(init_max_duration) {}

// NOLINTNEXTLINE(bugprone-unhandled-self-assignment,cert-oop54-cpp)
BenchmarkState& BenchmarkState::operator=(const BenchmarkState& other) {
  Assert(state != State::Running && other.state != State::Running, "Cannot assign to or from a running benchmark.");
  state = other.state.load();
  benchmark_begin = other.benchmark_begin;
  benchmark_duration = other.benchmark_duration;
  max_duration = other.max_duration;

  return *this;
}

bool BenchmarkState::keep_running() {
  switch (state) {
    case State::NotStarted:
      benchmark_begin = std::chrono::steady_clock::now();
      state = State::Running;
      break;
    case State::Over:
      return false;
    default: {
    }
  }

  benchmark_duration = std::chrono::steady_clock::now() - benchmark_begin;

  // Stop execution if we reached the time limit
  if (benchmark_duration >= max_duration) {
    set_done();
    return false;
  }

  return true;
}

void BenchmarkState::set_done() {
  state = State::Over;
}

bool BenchmarkState::is_done() const {
  return state == State::Over;
}

}  // namespace hyrise
