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

#include "rotor-light/queue.hpp"

using namespace rotor_light;

ItemQueueBase::ItemQueueBase(size_t item_size_, size_t items_count_)
    : buff_ptr(nullptr), item_size{static_cast<Index>(item_size_)},
      items_size{static_cast<Index>(items_count_)}, items_count{0},
      free_index{0}, occupied_index{0} {}

void ItemQueueBase::post_constructor(char *buff_) { buff_ptr = buff_; }

Message *ItemQueueBase::next() {
  if (items_count) {
    auto ptr = buff_ptr + item_size * occupied_index;
    return reinterpret_cast<Message *>(ptr);
  }
  return nullptr;
}

void ItemQueueBase::release() {
  if (occupied_index + 1 == items_size) {
    occupied_index = 0;
  } else {
    ++occupied_index;
  }
  --items_count;
}

QueueBase::QueueBase(ItemQueueBase **queues_, size_t queue_count_)
    : queues{queues_}, queue_count{static_cast<uint8_t>(queue_count_)} {}

ItemGuard QueueBase::next() {
  for (int i = static_cast<int>(queue_count - 1); i >= 0; --i) {
    auto &queue = queues[i];
    auto r = queue->next();
    if (r) {
      return {r, queue};
    }
  }
  return {};
}
