/*
 * 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;

    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 */
    int nextid; /* watch ID counter */
    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 = dir->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);
}
