#pragma once

#include "util.hpp"
#include "types.hpp"
#include "dns_updater.hpp"

#include <systemd/sd-event.h>

#include <sys/inotify.h>
#include <map>
#include <functional>
#include <experimental/filesystem>

namespace phosphor
{
namespace network
{
namespace inotify
{

namespace fs = std::experimental::filesystem;

// Auxiliary callback to be invoked on inotify events
using UserCallBack = std::function<void(const std::string&)>;

/** @class Watch
 *
 *  @brief Adds inotify watch on directory
 *
 *  @details Calls back user function on matching events
 */
class Watch
{
    public:
        Watch() = delete;
        Watch(const Watch&) = delete;
        Watch& operator=(const Watch&) = delete;
        Watch(Watch&&) = delete;
        Watch& operator=(Watch&&) = delete;

        /** @brief Hooks inotify watch with sd-event
         *
         *  @param[in] eventPtr - Reference to sd_event wrapped in unique_ptr
         *  @param[in] path     - File path to be watched
         *  @param[in] userFunc - User specific callback function on events
         *  @param[in] flags    - Flags to be supplied to inotify
         *  @param[in] mask     - Mask of events to be supplied to inotify
         *  @param[in] events   - Events to be watched
         */
        Watch(phosphor::network::EventPtr& eventPtr,
              const fs::path path,
              UserCallBack userFunc,
              int flags = IN_NONBLOCK,
              uint32_t mask = IN_CLOSE_WRITE,
              uint32_t events = EPOLLIN);

        /** @brief Remove inotify watch and close fd's */
        ~Watch()
        {
            if ((fd() >= 0) && (wd >= 0))
            {
                inotify_rm_watch(fd(), wd);
            }
        }

    private:
        /** @brief Callback invoked when inotify event fires
         *
         *  @details On a matching event, calls back into user supplied
         *           function if there is one registered
         *
         *  @param[in] eventSource - Event source
         *  @param[in] fd          - Inotify fd
         *  @param[in] retEvents   - Events that matched for fd
         *  @param[in] userData    - Pointer to Watch object
         *
         *  @returns 0 on success, -1 on fail
         */
        static int processEvents(sd_event_source* eventSource,
                                 int fd,
                                 uint32_t retEvents,
                                 void* userData);

        /** @brief Initializes an inotify instance
         *
         *  @return Descriptor on success, -1 on failure
         */
        int inotifyInit();

        /** @brief File path to be watched */
        const fs::path path;

        /** @brief User callback function */
        UserCallBack userFunc;

        /** @brief Inotify flags */
        int flags;

        /** @brief Mask of events */
        uint32_t mask;

        /** @brief Events to be watched */
        uint32_t events;

        /** @brief Watch descriptor */
        int wd = -1;

        /** @brief File descriptor manager */
        phosphor::Descriptor fd;
};

} // namespace inotify
} // namespace network
} // namespace phosphor
