// SPDX-License-Identifier: Apache-2.0
// Copyright (C) 2020 YADRO

#pragma once

#include <systemd/sd-bus.h>

#include <functional>
#include <map>
#include <set>
#include <string>
#include <vector>

/**
 * @class DbusLoop
 * @brief D-Bus based event loop.
 */
class DbusLoop
{
  public:
    /** @brief Set of possible values of the property. */
    using PropertyValues = std::set<std::string>;
    /** @brief Map of properties: name -> watched values. */
    using Properties = std::map<std::string, PropertyValues>;
    /** @brief Map of watched properties: interface -> properties. */
    using WatchProperties = std::map<std::string, Properties>;

    DbusLoop();
    virtual ~DbusLoop();

    /**
     * @brief Run worker loop.
     *
     * @return exit code from loop
     */
    virtual int run() const;

    /**
     * @brief Stop worker loop.
     *
     * @param[in] code exit code
     */
    void stop(int code) const;

    /**
     * @brief Add property change handler.
     *
     * @param[in] service D-Bus service name (object owner)
     * @param[in] objPath path to the D-Bus object
     * @param[in] props watched properties description
     * @param[in] callback function to call when property get one the listed
     *            values
     *
     * @throw std::system_error in case of errors
     */
    virtual void addPropertyHandler(const std::string& objPath,
                                    const WatchProperties& props,
                                    std::function<void()> callback);

    /**
     * @brief Add IO event handler.
     *
     * @param[in] fd file descriptor to watch
     * @param[in] callback function to call when IO event is occurred
     *
     * @throw std::system_error in case of errors
     */
    virtual void addIoHandler(int fd, std::function<void()> callback);

    /**
     * @brief Add signal handler.
     *
     * @param[in] signal signal to watch
     * @param[in] callback function to call when signal is triggered
     *
     * @throw std::system_error in case of errors
     */
    virtual void addSignalHandler(int signal, std::function<void()> callback);

  private:
    /**
     * @brief D-Bus callback: message handler.
     *        See sd_bus_message_handler_t for details.
     */
    static int msgCallback(sd_bus_message* msg, void* userdata,
                           sd_bus_error* err);

    /**
     * @brief D-Bus callback: signal handler.
     *        See sd_event_signal_handler_t for details.
     */
    static int signalCallback(sd_event_source* src,
                              const struct signalfd_siginfo* si,
                              void* userdata);

    /**
     * @brief D-Bus callback: IO handler.
     *        See sd_event_io_handler_t for details.
     */
    static int ioCallback(sd_event_source* src, int fd, uint32_t revents,
                          void* userdata);

  private:
    /** @brief D-Bus connection. */
    sd_bus* bus;
    /** @brief D-Bus event loop. */
    sd_event* event;

    /** @brief Watched properties. */
    WatchProperties propWatch;
    /** @brief Property change handler. */
    std::function<void()> propHandler;

    /** @brief IO handler. */
    std::function<void()> ioHandler;

    /** @brief Signal handlers. */
    std::map<int, std::function<void()>> signalHandlers;
};
