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

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) {
        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;
}
