/*
 * Copyright (c) 2009-2015 Travis Geiselbrecht
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files
 * (the "Software"), to deal in the Software without restriction,
 * including without limitation the rights to use, copy, modify, merge,
 * publish, distribute, sublicense, and/or sell copies of the Software,
 * and to permit persons to whom the Software is furnished to do so,
 * subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */
#include <debug.h>
#include <trace.h>
#include <list.h>
#include <err.h>
#include <string.h>
#include <stdlib.h>
#include <lib/fs.h>
#include <lib/bio.h>
#include <lk/init.h>
#include <kernel/mutex.h>

#define LOCAL_TRACE 0

struct fs_mount {
    struct list_node node;

    char *path;
    bdev_t *dev;
    fscookie *cookie;
    int ref;
    const struct fs_api *api;
};

struct filehandle {
    filecookie *cookie;
    struct fs_mount *mount;
};

struct dirhandle {
    dircookie *cookie;
    struct fs_mount *mount;
};

static mutex_t mount_lock = MUTEX_INITIAL_VALUE(mount_lock);
static struct list_node mounts = LIST_INITIAL_VALUE(mounts);
static struct list_node fses = LIST_INITIAL_VALUE(fses);

// defined in the linker script
extern const struct fs_impl __fs_impl_start;
extern const struct fs_impl __fs_impl_end;

static const struct fs_impl *find_fs(const char *name)
{
    for (const struct fs_impl *fs = &__fs_impl_start; fs != &__fs_impl_end; fs++) {
        if (!strcmp(name, fs->name))
            return fs;
    }
    return NULL;
}


// find a mount structure based on the prefix of this path
// bump the ref to the mount structure before returning
static struct fs_mount *find_mount(const char *path, const char **trimmed_path)
{
    struct fs_mount *mount;
    size_t pathlen = strlen(path);

    mutex_acquire(&mount_lock);
    list_for_every_entry(&mounts, mount, struct fs_mount, node) {
        size_t mountpathlen = strlen(mount->path);
        if (pathlen < mountpathlen)
            continue;

        LTRACEF("comparing %s with %s\n", path, mount->path);

        if (memcmp(path, mount->path, mountpathlen) == 0) {
            if (trimmed_path)
                *trimmed_path = &path[mountpathlen];

            mount->ref++;

            mutex_release(&mount_lock);
            return mount;
        }
    }

    mutex_release(&mount_lock);
    return NULL;
}

// decrement the ref to the mount structure, which may
// cause an unmount operation
static void put_mount(struct fs_mount *mount)
{
    mutex_acquire(&mount_lock);
    if ((--mount->ref) == 0) {
        list_delete(&mount->node);
        mount->api->unmount(mount->cookie);
        free(mount->path);
        if (mount->dev)
            bio_close(mount->dev);
        free(mount);
    }
    mutex_release(&mount_lock);
}

static status_t mount(const char *path, const char *device, const struct fs_api *api)
{
    struct fs_mount *mount;
    char temppath[FS_MAX_PATH_LEN];

    strlcpy(temppath, path, sizeof(temppath));
    fs_normalize_path(temppath);

    if (temppath[0] != '/')
        return ERR_BAD_PATH;

    /* see if there's already something at this path, abort if there is */
    mount = find_mount(temppath, NULL);
    if (mount) {
        put_mount(mount);
        return ERR_ALREADY_MOUNTED;
    }

    /* open a bio device if the string is nonnull */
    bdev_t *dev = NULL;
    if (device && device[0] != '\0') {
        dev = bio_open(device);
        if (!dev)
            return ERR_NOT_FOUND;
    }

    /* call into the fs implementation */
    fscookie *cookie;
    status_t err = api->mount(dev, &cookie);
    if (err < 0) {
        if (dev) bio_close(dev);
        return err;
    }

    /* create the mount structure and add it to the list */
    mount = malloc(sizeof(struct fs_mount));
    mount->path = strdup(temppath);
    mount->dev = dev;
    mount->cookie = cookie;
    mount->ref = 1;
    mount->api = api;

    list_add_head(&mounts, &mount->node);

    return 0;

}

status_t fs_format_device(const char *fsname, const char *device, const void *args)
{
    const struct fs_impl *fs = find_fs(fsname);
    if (!fs) {
        return ERR_NOT_FOUND;
    }

    if (fs->api->format == NULL) {
        return ERR_NOT_SUPPORTED;
    }

    bdev_t *dev = NULL;
    if (device && device[0] != '\0') {
        dev = bio_open(device);
        if (!dev)
            return ERR_NOT_FOUND;
    }

    return fs->api->format(dev, args);
}

status_t fs_mount(const char *path, const char *fsname, const char *device)
{
    const struct fs_impl *fs = find_fs(fsname);
    if (!fs)
        return ERR_NOT_FOUND;

    return mount(path, device, fs->api);
}

status_t fs_unmount(const char *path)
{
    char temppath[FS_MAX_PATH_LEN];

    strlcpy(temppath, path, sizeof(temppath));
    fs_normalize_path(temppath);

    struct fs_mount *mount = find_mount(temppath, NULL);
    if (!mount)
        return ERR_NOT_FOUND;

    // return the ref that find_mount added and one extra
    put_mount(mount);
    put_mount(mount);

    return 0;
}


status_t fs_open_file(const char *path, filehandle **handle)
{
    char temppath[FS_MAX_PATH_LEN];

    strlcpy(temppath, path, sizeof(temppath));
    fs_normalize_path(temppath);

    LTRACEF("path %s temppath %s\n", path, temppath);

    const char *newpath;
    struct fs_mount *mount = find_mount(temppath, &newpath);
    if (!mount)
        return ERR_NOT_FOUND;

    LTRACEF("path %s temppath %s newpath %s\n", path, temppath, newpath);

    filecookie *cookie;
    status_t err = mount->api->open(mount->cookie, newpath, &cookie);
    if (err < 0) {
        put_mount(mount);
        return err;
    }

    filehandle *f = malloc(sizeof(*f));
    f->cookie = cookie;
    f->mount = mount;
    *handle = f;

    return 0;
}

status_t fs_file_ioctl(filehandle *handle, int request, void *argp)
{
    LTRACEF("filehandle %p, request %d, argp, %p\n", handle, request, argp);

    if (unlikely(!handle || !handle->mount ||
                 !handle->mount->api || !handle->mount->api->file_ioctl)) {
        return ERR_INVALID_ARGS;
    }

    return handle->mount->api->file_ioctl(handle->cookie, request, argp);
}

status_t fs_create_file(const char *path, filehandle **handle, uint64_t len)
{
    char temppath[FS_MAX_PATH_LEN];

    strlcpy(temppath, path, sizeof(temppath));
    fs_normalize_path(temppath);

    const char *newpath;
    struct fs_mount *mount = find_mount(temppath, &newpath);
    if (!mount)
        return ERR_NOT_FOUND;

    if (!mount->api->create) {
        put_mount(mount);
        return ERR_NOT_SUPPORTED;
    }

    filecookie *cookie;
    status_t err = mount->api->create(mount->cookie, newpath, &cookie, len);
    if (err < 0) {
        put_mount(mount);
        return err;
    }

    filehandle *f = malloc(sizeof(*f));
    f->cookie = cookie;
    f->mount = mount;
    *handle = f;

    return 0;
}

status_t fs_remove_file(const char *path)
{
    char temppath[FS_MAX_PATH_LEN];

    strlcpy(temppath, path, sizeof(temppath));
    fs_normalize_path(temppath);

    const char *newpath;
    struct fs_mount *mount = find_mount(temppath, &newpath);
    if (!mount)
        return ERR_NOT_FOUND;

    if (!mount->api->remove) {
        put_mount(mount);
        return ERR_NOT_SUPPORTED;
    }

    status_t err = mount->api->remove(mount->cookie, newpath);

    put_mount(mount);

    return err;
}

ssize_t fs_read_file(filehandle *handle, void *buf, off_t offset, size_t len)
{
    return handle->mount->api->read(handle->cookie, buf, offset, len);
}

ssize_t fs_write_file(filehandle *handle, const void *buf, off_t offset, size_t len)
{
    if (!handle->mount->api->write)
        return ERR_NOT_SUPPORTED;

    return handle->mount->api->write(handle->cookie, buf, offset, len);
}

status_t fs_close_file(filehandle *handle)
{
    status_t err = handle->mount->api->close(handle->cookie);
    if (err < 0)
        return err;

    put_mount(handle->mount);
    free(handle);
    return 0;
}

status_t fs_stat_file(filehandle *handle, struct file_stat *stat)
{
    return handle->mount->api->stat(handle->cookie, stat);
}

status_t fs_make_dir(const char *path)
{
    char temppath[FS_MAX_PATH_LEN];

    strlcpy(temppath, path, sizeof(temppath));
    fs_normalize_path(temppath);

    const char *newpath;
    struct fs_mount *mount = find_mount(temppath, &newpath);
    if (!mount)
        return ERR_NOT_FOUND;

    if (!mount->api->mkdir) {
        put_mount(mount);
        return ERR_NOT_SUPPORTED;
    }

    status_t err = mount->api->mkdir(mount->cookie, newpath);

    put_mount(mount);

    return err;
}

status_t fs_open_dir(const char *path, dirhandle **handle)
{
    char temppath[FS_MAX_PATH_LEN];

    strlcpy(temppath, path, sizeof(temppath));
    fs_normalize_path(temppath);

    LTRACEF("path %s temppath %s\n", path, temppath);

    const char *newpath;
    struct fs_mount *mount = find_mount(temppath, &newpath);
    if (!mount)
        return ERR_NOT_FOUND;

    LTRACEF("path %s temppath %s newpath %s\n", path, temppath, newpath);

    if (!mount->api->opendir) {
        put_mount(mount);
        return ERR_NOT_SUPPORTED;
    }

    dircookie *cookie;
    status_t err = mount->api->opendir(mount->cookie, newpath, &cookie);
    if (err < 0) {
        put_mount(mount);
        return err;
    }

    dirhandle *d = malloc(sizeof(*d));
    d->cookie = cookie;
    d->mount = mount;
    *handle = d;

    return 0;
}

status_t fs_read_dir(dirhandle *handle, struct dirent *ent)
{
    if (!handle->mount->api->readdir)
        return ERR_NOT_SUPPORTED;

    return handle->mount->api->readdir(handle->cookie, ent);
}

status_t fs_close_dir(dirhandle *handle)
{
    if (!handle->mount->api->closedir)
        return ERR_NOT_SUPPORTED;

    status_t err = handle->mount->api->closedir(handle->cookie);
    if (err < 0)
        return err;

    put_mount(handle->mount);
    free(handle);
    return 0;
}

status_t fs_stat_fs(const char *mountpoint, struct fs_stat *stat)
{
    LTRACEF("mountpoint %s stat %p\n", mountpoint, stat);

    if (!stat) {
        return ERR_INVALID_ARGS;
    }

    const char *newpath;
    struct fs_mount *mount = find_mount(mountpoint, &newpath);
    if (!mount) {
        return ERR_NOT_FOUND;
    }

    if (!mount->api->fs_stat) {
        put_mount(mount);
        return ERR_NOT_SUPPORTED;
    }

    status_t result = mount->api->fs_stat(mount->cookie, stat);

    put_mount(mount);

    return result;
}


ssize_t fs_load_file(const char *path, void *ptr, size_t maxlen)
{
    filehandle *handle;

    /* open the file */
    status_t err = fs_open_file(path, &handle);
    if (err < 0)
        return err;

    /* stat it for size, see how much we need to read */
    struct file_stat stat;
    fs_stat_file(handle, &stat);

    ssize_t read_bytes = fs_read_file(handle, ptr, 0, MIN(maxlen, stat.size));

    fs_close_file(handle);

    return read_bytes;
}

const char *trim_name(const char *_name)
{
    const char *name = &_name[0];
    // chew up leading spaces
    while (*name == ' ')
        name++;

    // chew up leading slashes
    while (*name == '/')
        name++;

    return name;
}


void fs_normalize_path(char *path)
{
    int outpos;
    int pos;
    char c;
    bool done;
    enum {
        INITIAL,
        FIELD_START,
        IN_FIELD,
        SEP,
        SEEN_SEP,
        DOT,
        SEEN_DOT,
        DOTDOT,
        SEEN_DOTDOT,
    } state;

    state = INITIAL;
    pos = 0;
    outpos = 0;
    done = false;

    /* remove duplicate path seperators, flatten empty fields (only composed of .), backtrack fields with .., remove trailing slashes */
    while (!done) {
        c = path[pos];
        switch (state) {
            case INITIAL:
                if (c == '/') {
                    state = SEP;
                } else if (c == '.') {
                    state = DOT;
                } else {
                    state = FIELD_START;
                }
                break;
            case FIELD_START:
                if (c == '.') {
                    state = DOT;
                } else if (c == 0) {
                    done = true;
                } else {
                    state = IN_FIELD;
                }
                break;
            case IN_FIELD:
                if (c == '/') {
                    state = SEP;
                } else if (c == 0) {
                    done = true;
                } else {
                    path[outpos++] = c;
                    pos++;
                }
                break;
            case SEP:
                pos++;
                path[outpos++] = '/';
                state = SEEN_SEP;
                break;
            case SEEN_SEP:
                if (c == '/') {
                    // eat it
                    pos++;
                } else if (c == 0) {
                    done = true;
                } else {
                    state = FIELD_START;
                }
                break;
            case DOT:
                pos++; // consume the dot
                state = SEEN_DOT;
                break;
            case SEEN_DOT:
                if (c == '.') {
                    // dotdot now
                    state = DOTDOT;
                } else if (c == '/') {
                    // a field composed entirely of a .
                    // consume the / and move directly to the SEEN_SEP state
                    pos++;
                    state = SEEN_SEP;
                } else if (c == 0) {
                    done = true;
                } else {
                    // a field prefixed with a .
                    // emit a . and move directly into the IN_FIELD state
                    path[outpos++] = '.';
                    state = IN_FIELD;
                }
                break;
            case DOTDOT:
                pos++; // consume the dot
                state = SEEN_DOTDOT;
                break;
            case SEEN_DOTDOT:
                if (c == '/' || c == 0) {
                    // a field composed entirely of '..'
                    // search back and consume a field we've already emitted
                    if (outpos > 0) {
                        // we have already consumed at least one field
                        outpos--;

                        // walk backwards until we find the next field boundary
                        while (outpos > 0) {
                            if (path[outpos - 1] == '/') {
                                break;
                            }
                            outpos--;
                        }
                    }
                    pos++;
                    state = SEEN_SEP;
                    if (c == 0)
                        done = true;
                } else {
                    // a field prefixed with ..
                    // emit the .. and move directly to the IN_FIELD state
                    path[outpos++] = '.';
                    path[outpos++] = '.';
                    state = IN_FIELD;
                }
                break;
        }
    }

    /* dont end with trailing slashes */
    if (outpos > 0 && path[outpos - 1] == '/')
        outpos--;

    path[outpos++] = 0;
}

