/*
 * 9p
 *
 * Copyright IBM, Corp. 2010
 *
 * Authors:
 *  Gautham R Shenoy <ego@in.ibm.com>
 *
 * This work is licensed under the terms of the GNU GPL, version 2.  See
 * the COPYING file in the top-level directory.
 */

#include "qemu/osdep.h"
#include "qapi/error.h"
#include "qemu-fsdev.h"
#include "qemu/queue.h"
#include "qemu/config-file.h"
#include "qemu/error-report.h"
#include "qemu/option.h"

/*
 * A table to store the various file systems and their callback operations.
 * -----------------
 * fstype | ops
 * -----------------
 *  local | local_ops
 *  .     |
 *  .     |
 *  .     |
 *  .     |
 * -----------------
 *  etc
 */
typedef struct FsDriverTable {
    const char *name;
    FileOperations *ops;
    const char **opts;
} FsDriverTable;

typedef struct FsDriverListEntry {
    FsDriverEntry fse;
    QTAILQ_ENTRY(FsDriverListEntry) next;
} FsDriverListEntry;

static QTAILQ_HEAD(, FsDriverListEntry) fsdriver_entries =
    QTAILQ_HEAD_INITIALIZER(fsdriver_entries);

#define COMMON_FS_DRIVER_OPTIONS "id", "fsdriver", "readonly"

static FsDriverTable FsDrivers[] = {
    {
        .name = "local",
        .ops = &local_ops,
        .opts = (const char * []) {
            COMMON_FS_DRIVER_OPTIONS,
            "security_model",
            "path",
            "writeout",
            "fmode",
            "dmode",
            "multidevs",
            "throttling.bps-total",
            "throttling.bps-read",
            "throttling.bps-write",
            "throttling.iops-total",
            "throttling.iops-read",
            "throttling.iops-write",
            "throttling.bps-total-max",
            "throttling.bps-read-max",
            "throttling.bps-write-max",
            "throttling.iops-total-max",
            "throttling.iops-read-max",
            "throttling.iops-write-max",
            "throttling.bps-total-max-length",
            "throttling.bps-read-max-length",
            "throttling.bps-write-max-length",
            "throttling.iops-total-max-length",
            "throttling.iops-read-max-length",
            "throttling.iops-write-max-length",
            "throttling.iops-size",
            NULL
        },
    },
    {
        .name = "synth",
        .ops = &synth_ops,
        .opts = (const char * []) {
            COMMON_FS_DRIVER_OPTIONS,
            NULL
        },
    },
    {
        .name = "proxy",
        .ops = &proxy_ops,
        .opts = (const char * []) {
            COMMON_FS_DRIVER_OPTIONS,
            "socket",
            "sock_fd",
            "writeout",
            NULL
        },
    },
};

static int validate_opt(void *opaque, const char *name, const char *value,
                        Error **errp)
{
    FsDriverTable *drv = opaque;
    const char **opt;

    for (opt = drv->opts; *opt; opt++) {
        if (!strcmp(*opt, name)) {
            return 0;
        }
    }

    error_setg(errp, "'%s' is invalid for fsdriver '%s'", name, drv->name);
    return -1;
}

int qemu_fsdev_add(QemuOpts *opts, Error **errp)
{
    int i;
    struct FsDriverListEntry *fsle;
    const char *fsdev_id = qemu_opts_id(opts);
    const char *fsdriver = qemu_opt_get(opts, "fsdriver");
    const char *writeout = qemu_opt_get(opts, "writeout");
    bool ro = qemu_opt_get_bool(opts, "readonly", 0);

    if (!fsdev_id) {
        error_setg(errp, "fsdev: No id specified");
        return -1;
    }

    if (fsdriver) {
        if (strncmp(fsdriver, "proxy", 5) == 0) {
            warn_report(
                "'-fsdev proxy' and '-virtfs proxy' are deprecated, use "
                "'local' instead of 'proxy, or consider deploying virtiofsd "
                "as alternative to 9p"
            );
        }

        for (i = 0; i < ARRAY_SIZE(FsDrivers); i++) {
            if (strcmp(FsDrivers[i].name, fsdriver) == 0) {
                break;
            }
        }

        if (i == ARRAY_SIZE(FsDrivers)) {
            error_setg(errp, "fsdev: fsdriver %s not found", fsdriver);
            return -1;
        }
    } else {
        error_setg(errp, "fsdev: No fsdriver specified");
        return -1;
    }

    if (qemu_opt_foreach(opts, validate_opt, &FsDrivers[i], errp)) {
        return -1;
    }

    fsle = g_malloc0(sizeof(*fsle));
    fsle->fse.fsdev_id = g_strdup(fsdev_id);
    fsle->fse.ops = FsDrivers[i].ops;
    if (writeout) {
        if (!strcmp(writeout, "immediate")) {
            fsle->fse.export_flags |= V9FS_IMMEDIATE_WRITEOUT;
        }
    }
    if (ro) {
        fsle->fse.export_flags |= V9FS_RDONLY;
    } else {
        fsle->fse.export_flags &= ~V9FS_RDONLY;
    }

    if (fsle->fse.ops->parse_opts) {
        if (fsle->fse.ops->parse_opts(opts, &fsle->fse, errp)) {
            g_free(fsle->fse.fsdev_id);
            g_free(fsle);
            return -1;
        }
    }

    QTAILQ_INSERT_TAIL(&fsdriver_entries, fsle, next);
    return 0;
}

FsDriverEntry *get_fsdev_fsentry(char *id)
{
    if (id) {
        struct FsDriverListEntry *fsle;

        QTAILQ_FOREACH(fsle, &fsdriver_entries, next) {
            if (strcmp(fsle->fse.fsdev_id, id) == 0) {
                return &fsle->fse;
            }
        }
    }
    return NULL;
}
