#include "watch.hpp"

#include <sys/inotify.h>
#include <unistd.h>

#include <phosphor-logging/lg2.hpp>

#include <cstddef>
#include <cstring>
#include <filesystem>
#include <stdexcept>
#include <string>

PHOSPHOR_LOG2_USING;

namespace pldm
{

namespace fw_update
{

using namespace std::string_literals;
namespace fs = std::filesystem;

Watch::Watch(sd_event* loop, std::function<int(std::string&)> imageCallback) :
    imageCallback(imageCallback)
{
    fd = inotify_init1(IN_NONBLOCK);
    if (fd == -1)
    {
        // Store a copy of errno, because the string creation below will
        // invalidate errno due to one more system calls.
        const auto ec = errno;
        error("Error {EC} {ERR} when calling inotify_init1.", "EC", ec, "ERR",
              std::strerror(ec));
        throw std::runtime_error(
            "inotify_init1 failed, errno="s + std::strerror(ec));
    }

    const auto rc = sd_event_add_io(loop, nullptr, fd, EPOLLIN, callback, this);
    if (rc < 0)
    {
        error("Error {EC} calling sd_event_add_io.", "EC", rc);
        throw std::runtime_error(
            "failed to add to event loop, rc="s + std::strerror(-rc));
    }

    setupWatch();
}

void Watch::setupWatch()
{
    // Check if FIRMWARE_PACKAGE_STAGING_DIR exists and create it if not.
    fs::path imgDirPath(FIRMWARE_PACKAGE_STAGING_DIR);
    if (!fs::is_directory(imgDirPath))
    {
        fs::create_directories(imgDirPath);
        info("Directory {DIR} wasn't found, so it was created.", "DIR",
             std::string(FIRMWARE_PACKAGE_STAGING_DIR));
    }

    wd = inotify_add_watch(fd, FIRMWARE_PACKAGE_STAGING_DIR,
                           IN_CLOSE_WRITE | IN_DELETE_SELF);
    if (wd == -1)
    {
        const auto ec = errno;
        close(fd);
        error("Error {EC} {ERR} calling inotify_add_watch.", "EC", ec, "ERR",
              std::strerror(ec));
        throw std::runtime_error(
            "inotify_add_watch failed, errno="s + std::strerror(ec));
    }
    info("Set up filesystem watch for {DIR}", "DIR",
         std::string(FIRMWARE_PACKAGE_STAGING_DIR));
}

Watch::~Watch()
{
    if (-1 != fd)
    {
        if (-1 != wd)
        {
            inotify_rm_watch(fd, wd);
        }
        close(fd);
    }
}

int Watch::callback(sd_event_source* /* s */, int fd, uint32_t revents,
                    void* userdata)
{
    if (!(revents & EPOLLIN))
    {
        return 0;
    }

    constexpr auto maxBytes = 1024;
    uint8_t buffer[maxBytes];
    auto bytes = read(fd, buffer, maxBytes);
    if (0 > bytes)
    {
        auto ec = errno;
        error("Error {EC} {ERR} reading inotify event.", "EC", ec, "ERR",
              std::strerror(ec));
        throw std::runtime_error(
            "failed to read inotify event, errno="s + std::strerror(ec));
    }

    auto offset = 0;
    while (offset < bytes)
    {
        auto event = reinterpret_cast<inotify_event*>(&buffer[offset]);
        if ((event->mask & IN_CLOSE_WRITE) && !(event->mask & IN_ISDIR))
        {
            info("Received IN_CLOSE_WRITE event on {DIR} for {FILE}", "DIR",
                 std::string(FIRMWARE_PACKAGE_STAGING_DIR), "FILE",
                 event->name);
            auto tarballPath =
                std::string{FIRMWARE_PACKAGE_STAGING_DIR} + '/' + event->name;
            auto rc = static_cast<Watch*>(userdata)->imageCallback(tarballPath);
            if (rc < 0)
            {
                error("Error ({EC}) processing image {IMAGE_PATH}", "EC", rc,
                      "IMAGE_PATH", tarballPath.c_str());
            }
        }
        else if (event->mask & IN_DELETE_SELF)
        {
            info("Received IN_DELETE_SELF event on {DIR}", "DIR",
                 std::string(FIRMWARE_PACKAGE_STAGING_DIR));
            auto* const watch = reinterpret_cast<Watch*>(userdata);
            watch->wd = -1;
            // IN_DELETE_SELF event automatically cleans up the filesystem
            // watch, so we can just go ahead and set it up again without
            // cleaning.
            watch->setupWatch();
        }

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

    return 0;
}

} // namespace fw_update
} // namespace pldm
