#pragma once

#include "types/duration_types.hpp"
#include "utils/set_exception.hpp"

#include <sdbusplus/asio/object_server.hpp>
#include <sdbusplus/asio/property.hpp>

#include <future>
#include <thread>

#include <gmock/gmock.h>

class DbusEnvironment : public ::testing::Environment
{
  public:
    ~DbusEnvironment();

    void SetUp() override;
    void TearDown() override;
    void teardown();

    static boost::asio::io_context& getIoc();
    static std::shared_ptr<sdbusplus::asio::connection> getBus();
    static std::shared_ptr<sdbusplus::asio::object_server> getObjServer();
    static const char* serviceName();
    static std::function<void()> setPromise(std::string_view name);
    static void sleepFor(Milliseconds);
    static Milliseconds measureTime(std::function<void()>);

    static void synchronizeIoc()
    {
        while (ioc.poll() > 0)
        {}
    }

    template <class Functor>
    static void synchronizedPost(Functor&& functor)
    {
        boost::asio::post(ioc, std::forward<Functor>(functor));
        synchronizeIoc();
    }

    template <class T, class F>
    static T waitForFutures(std::vector<std::future<T>> futures, T init,
                            F&& accumulator,
                            Milliseconds timeout = std::chrono::seconds(10))
    {
        constexpr auto precission = Milliseconds(10);
        auto elapsed = Milliseconds(0);

        auto sum = init;
        for (auto& future : futures)
        {
            while (future.valid() && elapsed < timeout)
            {
                synchronizeIoc();

                if (future.wait_for(precission) == std::future_status::ready)
                {
                    sum = accumulator(sum, future.get());
                }
                else
                {
                    elapsed += precission;
                }
            }
        }

        if (elapsed >= timeout)
        {
            throw std::runtime_error("Timed out while waiting for future");
        }

        return sum;
    }

    template <class T>
    static T waitForFuture(std::future<T> future,
                           Milliseconds timeout = std::chrono::seconds(10))
    {
        std::vector<std::future<T>> futures;
        futures.emplace_back(std::move(future));

        return waitForFutures(
            std::move(futures), T{},
            [](auto, const auto& value) { return value; }, timeout);
    }

    static bool waitForFuture(std::string_view name,
                              Milliseconds timeout = std::chrono::seconds(10));

    static bool waitForFutures(std::string_view name,
                               Milliseconds timeout = std::chrono::seconds(10));

    template <class T>
    static T getProperty(const std::string& path,
                         const std::string& interfaceName,
                         const std::string& property)
    {
        auto propertyPromise = std::promise<T>();
        auto propertyFuture = propertyPromise.get_future();
        sdbusplus::asio::getProperty<T>(
            *DbusEnvironment::getBus(), DbusEnvironment::serviceName(), path,
            interfaceName, property,
            [&propertyPromise](const boost::system::error_code& ec, T t) {
            if (ec)
            {
                utils::setException(propertyPromise, "GetProperty failed");
                return;
            }
            propertyPromise.set_value(t);
            });
        return DbusEnvironment::waitForFuture(std::move(propertyFuture));
    }

    template <class T>
    static boost::system::error_code
        setProperty(const std::string& path, const std::string& interfaceName,
                    const std::string& property, const T& newValue)
    {
        auto promise = std::promise<boost::system::error_code>();
        auto future = promise.get_future();
        sdbusplus::asio::setProperty(
            *DbusEnvironment::getBus(), DbusEnvironment::serviceName(), path,
            interfaceName, property, std::move(newValue),
            [promise = std::move(promise)](
                boost::system::error_code ec) mutable {
            promise.set_value(ec);
            });
        return DbusEnvironment::waitForFuture(std::move(future));
    }

  private:
    static std::future<bool> getFuture(std::string_view name);

    static boost::asio::io_context ioc;
    static std::shared_ptr<sdbusplus::asio::connection> bus;
    static std::shared_ptr<sdbusplus::asio::object_server> objServer;
    static std::map<std::string, std::vector<std::future<bool>>> futures;
    static bool setUp;
};
