/*
 * SPDX-FileCopyrightText: Copyright OpenBMC Authors
 * SPDX-License-Identifier: Apache-2.0
 */

#include "SerialQueue.hpp"

#include <boost/asio/io_context.hpp>

#include <memory>
#include <optional>
#include <utility>
#include <vector>

#include <gtest/gtest.h>

namespace
{

class SerialQueueTest : public ::testing::Test
{
  protected:
    // Shared across the fixture's tests so the binary creates a single
    // io_uring instance. A per-test io_context exhausts the io_uring / locked
    // memory budget in constrained CI containers (io_uring_queue_init ENOMEM).
    inline static boost::asio::io_context io;
    std::shared_ptr<SerialQueue> queue = std::make_shared<SerialQueue>(io);

    // The io_context is shared, so reset its stopped state before each test;
    // poll() leaves it stopped once drained.
    void SetUp() override
    {
        io.restart();
    }

    // restart() before each poll so successive pumps process newly posted
    // handlers.
    static void pump()
    {
        io.restart();
        io.poll();
    }
};

TEST_F(SerialQueueTest, SubmitOnIdleRunsImmediately)
{
    bool ran = false;
    queue->submit([&ran](SerialQueue::ReleaseHandle /*handle*/) {
        ran = true;
    });
    EXPECT_TRUE(ran);
}

TEST_F(SerialQueueTest, SecondSubmitQueuedUntilFirstReleases)
{
    std::optional<SerialQueue::ReleaseHandle> heldA;
    bool ranA = false;
    bool ranB = false;

    queue->submit([&](SerialQueue::ReleaseHandle handle) {
        ranA = true;
        heldA = std::move(handle); // keep the slot reserved
    });
    queue->submit([&](SerialQueue::ReleaseHandle /*handle*/) { ranB = true; });

    EXPECT_TRUE(ranA);
    EXPECT_FALSE(ranB); // B is queued behind A

    heldA.reset();      // release A's slot -> posts B
    EXPECT_FALSE(ranB); // dispatch is via io.post(), not inline
    io.poll();
    EXPECT_TRUE(ranB);
}

TEST_F(SerialQueueTest, TasksRunInFifoOrder)
{
    std::vector<int> order;
    std::optional<SerialQueue::ReleaseHandle> held;

    auto makeTask = [&](int id) {
        return [&order, &held, id](SerialQueue::ReleaseHandle handle) {
            order.push_back(id);
            held = std::move(handle);
        };
    };

    queue->submit(makeTask(1));
    queue->submit(makeTask(2));
    queue->submit(makeTask(3));

    // Task 1 ran inline; release sequentially, pumping between each.
    held.reset();
    pump();
    held.reset();
    pump();
    held.reset();
    pump();

    ASSERT_EQ(order.size(), 3U);
    EXPECT_EQ(order[0], 1);
    EXPECT_EQ(order[1], 2);
    EXPECT_EQ(order[2], 3);
}

TEST_F(SerialQueueTest, ReleaseHandleMoveTransfersOwnership)
{
    std::optional<SerialQueue::ReleaseHandle> heldA;
    bool ranB = false;

    queue->submit([&](SerialQueue::ReleaseHandle handle) {
        heldA = std::move(handle);
    });
    queue->submit([&](SerialQueue::ReleaseHandle /*handle*/) { ranB = true; });

    // Move ownership to another handle; the moved-from slot must not release.
    std::optional<SerialQueue::ReleaseHandle> heldMoved = std::move(heldA);
    // NOLINTNEXTLINE(bugprone-use-after-move): moved-from reset is the point
    heldA.reset();
    pump();
    EXPECT_FALSE(ranB);

    // Releasing the owning handle dispatches B exactly once.
    heldMoved.reset();
    pump();
    EXPECT_TRUE(ranB);
}

TEST_F(SerialQueueTest, EmptyQueueReleaseResetsInFlight)
{
    bool ranFirst = false;
    queue->submit([&ranFirst](SerialQueue::ReleaseHandle /*handle*/) {
        ranFirst = true;
    });
    EXPECT_TRUE(ranFirst);

    // Queue returned to idle; a later submit must again run inline.
    bool ranSecond = false;
    queue->submit([&ranSecond](SerialQueue::ReleaseHandle /*handle*/) {
        ranSecond = true;
    });
    EXPECT_TRUE(ranSecond);
}

TEST_F(SerialQueueTest, DestroyQueueWithPendingTasksNoCrash)
{
    std::optional<SerialQueue::ReleaseHandle> held;

    queue->submit([&](SerialQueue::ReleaseHandle handle) {
        held = std::move(handle);
    });
    queue->submit([](SerialQueue::ReleaseHandle /*handle*/) {});

    // Drop the queue while a handle is still outstanding.
    queue.reset();
    EXPECT_NO_THROW(held.reset()); // ReleaseHandle::reset no-ops if queue gone
    EXPECT_NO_THROW(io.poll());
}

} // namespace
