/*
 * QEMU file monitor Linux inotify impl
 *
 * Copyright (c) 2018 Red Hat, Inc.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
 *
 */

#include "qemu/osdep.h"
#include "qemu/filemonitor.h"
#include "qemu/main-loop.h"
#include "qemu/error-report.h"
#include "qapi/error.h"
#include "trace.h"

#include <sys/inotify.h>

struct QFileMonitor {
    int fd;
    int nextid; /* watch ID counter */
    QemuMutex lock; /* protects dirs & idmap */
    GHashTable *dirs; /* dirname => QFileMonitorDir */
    GHashTable *idmap; /* inotify ID => dirname */
};


typedef struct {
    int id; /* watch ID */
    char *filename; /* optional filter */
    QFileMonitorHandler cb;
    void *opaque;
} QFileMonitorWatch;


typedef struct {
    char *path;
    int id; /* inotify ID */
    GArray *watches; /* QFileMonitorWatch elements */
} QFileMonitorDir;


static void qemu_file_monitor_watch(void *arg)
{
    QFileMonitor *mon = arg;
    char buf[4096]
        __attribute__ ((aligned(__alignof__(struct inotify_event))));
    int used = 0;
    int len;

    qemu_mutex_lock(&mon->lock);

    if (mon->fd == -1) {
        qemu_mutex_unlock(&mon->lock);
        return;
    }

    len = read(mon->fd, buf, sizeof(buf));

    if (len < 0) {
        if (errno != EAGAIN) {
            error_report("Failure monitoring inotify FD '%s',"
                         "disabling events", strerror(errno));
            goto cleanup;
        }

        /* no more events right now */
        goto cleanup;
    }

    /* Loop over all events in the buffer */
    while (used < len) {
        struct inotify_event *ev =
            (struct inotify_event *)(buf + used);
        const char *name = ev->len ? ev->name : "";
        QFileMonitorDir *dir = g_hash_table_lookup(mon->idmap,
                                                   GINT_TO_POINTER(ev->wd));
        uint32_t iev = ev->mask &
            (IN_CREATE | IN_MODIFY | IN_DELETE | IN_IGNORED |
             IN_MOVED_TO | IN_MOVED_FROM | IN_ATTRIB);
        int qev;
        gsize i;

        used += sizeof(struct inotify_event) + ev->len;

        if (!dir) {
            continue;
        }

        /*
         * During a rename operation, the old name gets
         * IN_MOVED_FROM and the new name gets IN_MOVED_TO.
         * To simplify life for callers, we turn these into
         * DELETED and CREATED events
         */
        switch (iev) {
        case IN_CREATE:
        case IN_MOVED_TO:
            qev = QFILE_MONITOR_EVENT_CREATED;
            break;
        case IN_MODIFY:
            qev = QFILE_MONITOR_EVENT_MODIFIED;
            break;
        case IN_DELETE:
        case IN_MOVED_FROM:
            qev = QFILE_MONITOR_EVENT_DELETED;
            break;
        case IN_ATTRIB:
            qev = QFILE_MONITOR_EVENT_ATTRIBUTES;
            break;
        case IN_IGNORED:
            qev = QFILE_MONITOR_EVENT_IGNORED;
            break;
        default:
            g_assert_not_reached();
        }

        trace_qemu_file_monitor_event(mon, dir->path, name, ev->mask, dir->id);
        for (i = 0; i < dir->watches->len; i++) {
            QFileMonitorWatch *watch = &g_array_index(dir->watches,
                                                      QFileMonitorWatch,
                                                      i);

            if (watch->filename == NULL ||
                (name && g_str_equal(watch->filename, name))) {
                trace_qemu_file_monitor_dispatch(mon, dir->path, name,
                                                 qev, watch->cb,
                                                 watch->opaque, watch->id);
                watch->cb(watch->id, qev, name, watch->opaque);
            }
        }
    }

 cleanup:
    qemu_mutex_unlock(&mon->lock);
}


static void
qemu_file_monitor_dir_free(void *data)
{
    QFileMonitorDir *dir = data;
    gsize i;

    for (i = 0; i < dir->watches->len; i++) {
        QFileMonitorWatch *watch = &g_array_index(dir->watches,
                                                  QFileMonitorWatch, i);
        g_free(watch->filename);
    }
    g_array_unref(dir->watches);
    g_free(dir->path);
    g_free(dir);
}


QFileMonitor *
qemu_file_monitor_new(Error **errp)
{
    int fd;
    QFileMonitor *mon;

    fd = inotify_init1(IN_NONBLOCK);
    if (fd < 0) {
        error_setg_errno(errp, errno,
                         "Unable to initialize inotify");
        return NULL;
    }

    mon = g_new0(QFileMonitor, 1);
    qemu_mutex_init(&mon->lock);
    mon->fd = fd;

    mon->dirs = g_hash_table_new_full(g_str_hash, g_str_equal, NULL,
                                      qemu_file_monitor_dir_free);
    mon->idmap = g_hash_table_new(g_direct_hash, g_direct_equal);

    trace_qemu_file_monitor_new(mon, mon->fd);

    return mon;
}

static gboolean
qemu_file_monitor_free_idle(void *opaque)
{
    QFileMonitor *mon = opaque;

    if (!mon) {
        return G_SOURCE_REMOVE;
    }

    qemu_mutex_lock(&mon->lock);

    g_hash_table_unref(mon->idmap);
    g_hash_table_unref(mon->dirs);

    qemu_mutex_unlock(&mon->lock);

    qemu_mutex_destroy(&mon->lock);
    g_free(mon);

    return G_SOURCE_REMOVE;
}

void
qemu_file_monitor_free(QFileMonitor *mon)
{
    if (!mon) {
        return;
    }

    qemu_mutex_lock(&mon->lock);
    if (mon->fd != -1) {
        qemu_set_fd_handler(mon->fd, NULL, NULL, NULL);
        close(mon->fd);
        mon->fd = -1;
    }
    qemu_mutex_unlock(&mon->lock);

    /*
     * Can't free it yet, because another thread
     * may be running event loop, so the inotify
     * callback might be pending. Using an idle
     * source ensures we'll only free after the
     * pending callback is done
     */
    g_idle_add((GSourceFunc)qemu_file_monitor_free_idle, mon);
}

int
qemu_file_monitor_add_watch(QFileMonitor *mon,
                            const char *dirpath,
                            const char *filename,
                            QFileMonitorHandler cb,
                            void *opaque,
                            Error **errp)
{
    QFileMonitorDir *dir;
    QFileMonitorWatch watch;
    int ret = -1;

    qemu_mutex_lock(&mon->lock);
    dir = g_hash_table_lookup(mon->dirs, dirpath);
    if (!dir) {
        int rv = inotify_add_watch(mon->fd, dirpath,
                                   IN_CREATE | IN_DELETE | IN_MODIFY |
                                   IN_MOVED_TO | IN_MOVED_FROM | IN_ATTRIB);

        if (rv < 0) {
            error_setg_errno(errp, errno, "Unable to watch '%s'", dirpath);
            goto cleanup;
        }

        trace_qemu_file_monitor_enable_watch(mon, dirpath, rv);

        dir = g_new0(QFileMonitorDir, 1);
        dir->path = g_strdup(dirpath);
        dir->id = rv;
        dir->watches = g_array_new(FALSE, TRUE, sizeof(QFileMonitorWatch));

        g_hash_table_insert(mon->dirs, dir->path, dir);
        g_hash_table_insert(mon->idmap, GINT_TO_POINTER(rv), dir);

        if (g_hash_table_size(mon->dirs) == 1) {
            qemu_set_fd_handler(mon->fd, qemu_file_monitor_watch, NULL, mon);
        }
    }

    watch.id = mon->nextid++;
    watch.filename = g_strdup(filename);
    watch.cb = cb;
    watch.opaque = opaque;

    g_array_append_val(dir->watches, watch);

    trace_qemu_file_monitor_add_watch(mon, dirpath,
                                      filename ? filename : "<none>",
                                      cb, opaque, watch.id);

    ret = watch.id;

 cleanup:
    qemu_mutex_unlock(&mon->lock);
    return ret;
}


void qemu_file_monitor_remove_watch(QFileMonitor *mon,
                                    const char *dirpath,
                                    int id)
{
    QFileMonitorDir *dir;
    gsize i;

    qemu_mutex_lock(&mon->lock);

    trace_qemu_file_monitor_remove_watch(mon, dirpath, id);

    dir = g_hash_table_lookup(mon->dirs, dirpath);
    if (!dir) {
        goto cleanup;
    }

    for (i = 0; i < dir->watches->len; i++) {
        QFileMonitorWatch *watch = &g_array_index(dir->watches,
                                                  QFileMonitorWatch, i);
        if (watch->id == id) {
            g_free(watch->filename);
            g_array_remove_index(dir->watches, i);
            break;
        }
    }

    if (dir->watches->len == 0) {
        inotify_rm_watch(mon->fd, dir->id);
        trace_qemu_file_monitor_disable_watch(mon, dir->path, dir->id);

        g_hash_table_remove(mon->idmap, GINT_TO_POINTER(dir->id));
        g_hash_table_remove(mon->dirs, dir->path);

        if (g_hash_table_size(mon->dirs) == 0) {
            qemu_set_fd_handler(mon->fd, NULL, NULL, NULL);
        }
    }

 cleanup:
    qemu_mutex_unlock(&mon->lock);
}
