// SPDX-License-Identifier: MIT
// SPDX-FileCopyrightText: 2022 Ivan Baidakou

#if defined(__ANDROID__)
#undef __ANDROID__
#endif

#include "catch.hpp"

#include "rotor-light/planner.hpp"
#include "rotor-light/queue.hpp"
#include "rotor-light/supervisor.hpp"

using namespace rotor_light;

struct Sample : Message {
  static constexpr auto type_id = __LINE__;
  using Message::Message;
};

using MessageStorage = traits::MessageStorage<message::ChangeState,
                                              message::ChangeStateAck, Sample>;

using AppQueue = Queue<MessageStorage, 5>;
using AppSupervisor = Supervisor<3>;
using AppPlanner = Planner<1>;

static int overfill = 0;

namespace rotor_light {

void on_queue_full() { ++overfill; }

} // namespace rotor_light

TEST_CASE("simple ping-pong example", "[actor]") {
  AppQueue queue;
  AppPlanner planner;
  Context context{&queue, &planner, nullptr};
  AppSupervisor sup;
  sup.bind(context);

  sup.start();
  sup.process();
  CHECK(overfill == 0);

  for (int i = 0; i < 5; ++i) {
    bool ok = sup.send<ctx::thread, Sample>(0, sup.get_id());
    CHECK(ok);
  }
  CHECK(overfill == 0);

  bool ok = sup.send<ctx::thread, Sample>(0, sup.get_id());
  CHECK(!ok);
  CHECK(overfill == 0);
  sup.stop();
  CHECK(overfill == 1);
  sup.process();

  sup.stop();
  sup.process();

  CHECK(sup.get_state() == State::off);
}
