/*
 * Copyright (c) 2009 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 <list.h>
#include <err.h>
#include <string.h>
#include <stdlib.h>
#include <lib/fs.h>
#include <lib/bio.h>

#if WITH_LIB_FS_EXT2
#include <lib/fs/ext2.h>
#endif
#if WITH_LIB_FS_FAT32
#include <lib/fs/fat32.h>
#endif

#define LOCAL_TRACE 0

struct fs_type {
	const char *name;
	int (*mount)(bdev_t *, fscookie *);
	int (*unmount)(fscookie);
	int (*open)(fscookie, const char *, filecookie *);
	int (*create)(fscookie, const char *, filecookie *);
	int (*mkdir)(fscookie, const char *);
	int (*stat)(filecookie, struct file_stat *);
	int (*read)(filecookie, void *, off_t, size_t);
	int (*write)(filecookie, const void *, off_t, size_t);
	int (*close)(filecookie);
};

struct fs_mount {
	struct list_node node;
	char *path;
	bdev_t *dev;
	fscookie cookie;
	int refs;
	struct fs_type *type;
};

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

static struct list_node mounts;

static struct fs_type types[] = {
#if WITH_LIB_FS_EXT2
	{
		.name = "ext2",
		.mount = ext2_mount,
		.unmount = ext2_unmount,
		.open = ext2_open_file,
		.stat = ext2_stat_file,
		.read = ext2_read_file,
		.close = ext2_close_file,
	},
#endif
#if WITH_LIB_FS_FAT32
	{
		.name = "fat32",
		.mount = fat32_mount,
		.unmount = fat32_unmount,
		.open = fat32_open_file,
		.create = fat32_create_file,
		.mkdir = fat32_make_dir,
		.stat = fat32_stat_file,
		.read = fat32_read_file,
		.write = fat32_write_file,
		.close = fat32_close_file,
	},
#endif
};

static void test_normalize(const char *in);
static struct fs_mount *find_mount(const char *path, const char **trimmed_path);

void fs_init(void)
{
	list_initialize(&mounts);
#if 0
	test_normalize("/");
	test_normalize("/test");
	test_normalize("/test/");
	test_normalize("test/");
	test_normalize("test");
	test_normalize("/test//");
	test_normalize("/test/foo");
	test_normalize("/test/foo/");
	test_normalize("/test/foo/bar");
	test_normalize("/test/foo/bar//");
	test_normalize("/test//foo/bar//");
	test_normalize("/test//./foo/bar//");
	test_normalize("/test//./.foo/bar//");
	test_normalize("/test//./..foo/bar//");
	test_normalize("/test//./../foo/bar//");
	test_normalize("/test/../foo");
	test_normalize("/test/bar/../foo");
	test_normalize("../foo");
	test_normalize("../foo/");
	test_normalize("/../foo");
	test_normalize("/../foo/");
	test_normalize("/../../foo");
	test_normalize("/bleh/../../foo");
	test_normalize("/bleh/bar/../../foo");
	test_normalize("/bleh/bar/../../foo/..");
	test_normalize("/bleh/bar/../../foo/../meh");
#endif
}

static struct fs_mount *find_mount(const char *path, const char **trimmed_path)
{
	struct fs_mount *mount;
	size_t pathlen = strlen(path);

	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];

			return mount;
		}
	}

	return NULL;
}

static int mount(const char *path, const char *device, struct fs_type *type)
{
	char temppath[512];

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

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

	if (find_mount(temppath, NULL))
		return ERR_ALREADY_MOUNTED;

	bdev_t *dev = bio_open(device);
	if (!dev)
		return ERR_NOT_FOUND;

	fscookie cookie;
	int err = type->mount(dev, &cookie);
	if (err < 0) {
		bio_close(dev);
		return err;
	}

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

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

	return 0;
}

int fs_mount(const char *path, const char *device)
{
	return mount(path, device, &types[0]);
}

int fs_mount_type(const char *path, const char *device, const char *name)
{
	size_t i;

	for (i = 0; i < countof(types); i++) {
		if (!strcmp(name, types[i].name))
			return mount(path, device, &types[i]);
	}

	return ERR_NOT_FOUND;
}

static void put_mount(struct fs_mount *mount)
{
	if (!(--mount->refs)) {
		list_delete(&mount->node);
		mount->type->unmount(mount->cookie);
		free(mount->path);
		bio_close(mount->dev);
		free(mount);
	}
}

int fs_unmount(const char *path)
{
	char temppath[512];

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

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

	put_mount(mount);

	return 0;
}


int fs_open_file(const char *path, filecookie *fcookie)
{
	int err;
	char temppath[512];
	filecookie cookie;

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

	err = mount->type->open(mount->cookie, newpath, &cookie);
	if (err < 0)
		return err;

	struct fs_file *f = malloc(sizeof(*f));
	f->cookie = cookie;
	f->mount = mount;
	mount->refs++;
	*fcookie = f;

	return 0;
}

int fs_create_file(const char *path, filecookie *fcookie)
{
	int err;
	char temppath[512];
	filecookie cookie;

	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->type->create)
		return ERR_NOT_SUPPORTED;

	err = mount->type->create(mount->cookie, newpath, &cookie);
	if (err < 0)
		return err;

	struct fs_file *f = malloc(sizeof(*f));
	f->cookie = cookie;
	f->mount = mount;
	mount->refs++;
	*fcookie = f;

	return 0;
}

int fs_make_dir(const char *path)
{
	char temppath[512];

	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->type->mkdir)
		return ERR_NOT_SUPPORTED;

	return mount->type->mkdir(mount->cookie, newpath);
}

int fs_read_file(filecookie fcookie, void *buf, off_t offset, size_t len)
{
	struct fs_file *f = fcookie;

	return f->mount->type->read(f->cookie, buf, offset, len);
}

int fs_write_file(filecookie fcookie, const void *buf, off_t offset, size_t len)
{
	struct fs_file *f = fcookie;

	if (!f->mount->type->write)
		return ERR_NOT_SUPPORTED;

	return f->mount->type->write(f->cookie, buf, offset, len);
}

int fs_close_file(filecookie fcookie)
{
	int err;
	struct fs_file *f = fcookie;

	err = f->mount->type->close(f->cookie);
	if (err < 0)
		return err;

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

int fs_stat_file(filecookie fcookie, struct file_stat *stat)
{
	struct fs_file *f = fcookie;

	return f->mount->type->stat(f->cookie, stat);
}

ssize_t fs_load_file(const char *path, void *ptr, size_t maxlen)
{
	int err;
	filecookie cookie;

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

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

	err = fs_read_file(cookie, ptr, 0, MIN(maxlen, stat.size));

	fs_close_file(cookie);

	return err;
}

static void test_normalize(const char *in)
{
	char path[1024];

	strlcpy(path, in, sizeof(path));
	fs_normalize_path(path);
	printf("'%s' -> '%s'\n", in, path);
}

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

