#include "watch.hpp"

#include "xyz/openbmc_project/Common/error.hpp"

#include <phosphor-logging/elog-errors.hpp>
#include <phosphor-logging/lg2.hpp>

#include <span>

namespace phosphor
{
namespace dump
{
namespace inotify
{

using namespace std::string_literals;
using namespace phosphor::logging;
using namespace sdbusplus::xyz::openbmc_project::Common::Error;

Watch::~Watch()
{
    if ((fd() >= 0) && (wd >= 0))
    {
        inotify_rm_watch(fd(), wd);
    }
}

Watch::Watch(const EventPtr& eventObj, const int flags, const uint32_t mask,
             const uint32_t events, const std::filesystem::path& path,
             UserType userFunc) :
    flags(flags), mask(mask), events(events), path(path), fd(inotifyInit()),
    userFunc(userFunc)
{
    // Check if watch DIR exists.
    if (!std::filesystem::is_directory(path))
    {
        lg2::error("Watch directory doesn't exist, DIR: {DIRECTORY}",
                   "DIRECTORY", path);
        elog<InternalFailure>();
    }

    wd = inotify_add_watch(fd(), path.c_str(), mask);
    if (-1 == wd)
    {
        auto error = errno;
        lg2::error(
            "Error occurred during the inotify_add_watch call, errno: {ERRNO}",
            "ERRNO", error);
        elog<InternalFailure>();
    }

    auto rc =
        sd_event_add_io(eventObj.get(), nullptr, fd(), events, callback, this);
    if (0 > rc)
    {
        // Failed to add to event loop
        lg2::error("Error occurred during the sd_event_add_io call, rc: {RC}",
                   "RC", rc);
        elog<InternalFailure>();
    }
}

int Watch::inotifyInit()
{
    auto fd = inotify_init1(flags);

    if (-1 == fd)
    {
        auto error = errno;
        lg2::error("Error occurred during the inotify_init1, errno: {ERRNO}",
                   "ERRNO", error);
        elog<InternalFailure>();
    }

    return fd;
}

int Watch::callback(sd_event_source*, int fd, uint32_t revents, void* userdata)
{
    auto userData = static_cast<Watch*>(userdata);

    if ((revents & userData->events) == 0U)
    {
        return 0;
    }

    // Maximum inotify events supported in the buffer
    constexpr auto maxBytes = sizeof(struct inotify_event) + NAME_MAX + 1;
    uint8_t buffer[maxBytes];

    std::span<char> bufferSpan(reinterpret_cast<char*>(buffer), maxBytes);
    auto bytes = read(fd, bufferSpan.data(), bufferSpan.size());
    if (0 > bytes)
    {
        // Failed to read inotify event
        // Report error and return
        auto error = errno;
        lg2::error("Error occurred during the read, errno: {ERRNO}", "ERRNO",
                   error);
        report<InternalFailure>();
        return 0;
    }

    auto offset = 0;

    UserMap userMap;

    while (offset < bytes)
    {
        auto event = reinterpret_cast<inotify_event*>(&buffer[offset]);
        auto mask = event->mask & userData->mask;

        if (mask != 0U)
        {
            userMap.emplace((userData->path / event->name), mask);
        }

        offset += offsetof(inotify_event, name) + event->len;
    }

    // Call user call back function in case valid data in the map
    if (!userMap.empty())
    {
        userData->userFunc(userMap);
    }

    return 0;
}

} // namespace inotify
} // namespace dump
} // namespace phosphor
