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

#pragma once

#include "MctpRequester.hpp"

#include <boost/asio/io_context.hpp>
#include <boost/system/error_code.hpp>
#include <sdbusplus/asio/connection.hpp>
#include <sdbusplus/asio/object_server.hpp>
#include <sdbusplus/asio/property.hpp>
#include <sdbusplus/exception.hpp>

#include <cerrno>
#include <chrono>
#include <functional>
#include <memory>
#include <optional>
#include <string>
#include <utility>

#include <gtest/gtest.h>

/**
 * Owns the private dbus-daemon and the shared bus objects for the whole
 * binary. Bring-up failure is not fatal: DbusMockTestBase fixtures skip
 * themselves, so pure-unit tests in the same binary still run.
 */
class DbusEnvironment : public ::testing::Environment
{
  public:
    void SetUp() override;
    void TearDown() override;
};

// Base fixture for tests that need the shared D-Bus session.
class DbusMockTestBase : public ::testing::Test
{
  protected:
    // Valid only while hasBus().
    static std::shared_ptr<sdbusplus::asio::connection>& bus();
    static sdbusplus::asio::object_server& objects();
    static mctp::MctpRequester& requester();
    static boost::asio::io_context& ioContext();

    static bool hasBus();

    // GTEST_SKIP() only returns from this function; derived overrides must
    // check testing::Test::IsSkipped() after delegating here.
    void SetUp() override;

    // Drains pending D-Bus work so the next test starts clean.
    void TearDown() override;

    // Run already-queued handlers so destructor-cancelled async ops finish.
    static void drainPendingAsync();

    /**
     * Read a property from this connection's own object server. Async +
     * io_context pump because sd-bus rejects self-directed synchronous calls
     * with ELOOP. Throws SdBusError on error or timeout.
     */
    template <typename PropertyType>
    static PropertyType getProperty(const std::string& path,
                                    const std::string& iface,
                                    const std::string& prop)
    {
        // Heap-owned handler state: a late reply may fire in a later pump,
        // after this frame has thrown ETIMEDOUT and unwound.
        struct State
        {
            std::optional<boost::system::error_code> ec;
            PropertyType value{};
        };
        auto state = std::make_shared<State>();

        sdbusplus::asio::getProperty<PropertyType>(
            *bus(), bus()->get_unique_name(), path, iface, prop,
            [state](boost::system::error_code ec, PropertyType value) {
                state->value = std::move(value);
                state->ec = ec;
            });

        if (!pumpIoUntil([state] { return state->ec.has_value(); },
                         propertyReadTimeout))
        {
            throw sdbusplus::exception::SdBusError(ETIMEDOUT,
                                                   "getProperty timed out");
        }

        const boost::system::error_code callError =
            state->ec.value_or(boost::system::error_code{});
        if (callError)
        {
            throw sdbusplus::exception::SdBusError(
                callError.value(),
                ("getProperty: " + callError.message()).c_str());
        }
        return std::move(state->value);
    }

    // Pump the shared io_context until done() holds; false on timeout. Needed
    // by tests that wait on a timer inside the object under test.
    static bool pumpIoUntil(const std::function<bool()>& done,
                            std::chrono::seconds timeout);

  private:
    friend class DbusEnvironment;

    static constexpr std::chrono::seconds propertyReadTimeout{5};

    static bool tryConnect();

    // Fresh instance per environment SetUp, never deleted: a late
    // ~connection() must not touch a destroyed io_uring service, and a
    // recreated environment must never run the previous lifetime's queued
    // raw-`this` handlers.
    static boost::asio::io_context* io;
    static std::shared_ptr<sdbusplus::asio::connection> conn;
    static std::unique_ptr<sdbusplus::asio::object_server> objectServer;
    static std::unique_ptr<mctp::MctpRequester> mctpRequester;
    static bool available;
    static std::string bringUpFailure;
};
