/*
 * Copyright (c) 2016 Intel Corporation
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <errno.h>
#include <stdio.h>
#include <string.h>

#include <misc/printk.h>
#include <shell/shell.h>
#include <init.h>
#include <fs.h>
#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>
#include <limits.h>

#define BUF_CNT 64

#define MAX_PATH_LEN 128
#define MAX_FILENAME_LEN 128
#define MAX_INPUT_LEN 20

static char cwd[MAX_PATH_LEN] = "/";

static void create_abs_path(const char *name, char *path, size_t len)
{
	if (name[0] == '/') {
		strncpy(path, name, len - 1);
		path[len - 1] = '\0';
	} else {
		if (strcmp(cwd, "/") == 0) {
			snprintf(path, len, "/%s", name);
		} else {
			snprintf(path, len, "%s/%s", cwd, name);
		}
	}
}

static int cmd_mkdir(int argc, char *argv[])
{
	int res;
	char path[MAX_PATH_LEN];

	if (argc < 2) {
		printk("Missing argument\n");
		return 0;
	}

	create_abs_path(argv[1], path, sizeof(path));

	res = fs_mkdir(path);
	if (res) {
		printk("Error creating dir[%d]\n", res);
		return res;
	}

	return 0;
}

static int cmd_rm(int argc, char *argv[])
{
	int err;
	char path[MAX_PATH_LEN];

	if (argc < 2) {
		printk("Missing argument\n");
		return 0;
	}

	create_abs_path(argv[1], path, sizeof(path));

	err = fs_unlink(path);
	if (err) {
		printk("Failed to remove %s (%d)\n", path, err);
		return err;
	}

	return 0;
}

static int cmd_read(int argc, char *argv[])
{
	char path[MAX_PATH_LEN];
	struct fs_dirent dirent;
	struct fs_file_t file;
	int count;
	off_t offset;
	int err;

	if (argc < 2) {
		printk("Missing argument\n");
		return 0;
	}

	create_abs_path(argv[1], path, sizeof(path));

	if (argc > 2) {
		count = strtol(argv[2], NULL, 0);
		if (count <= 0) {
			count = INT_MAX;
		}
	} else {
		count = INT_MAX;
	}

	if (argc > 3) {
		offset = strtol(argv[3], NULL, 0);
	} else {
		offset = 0;
	}

	err = fs_stat(path, &dirent);
	if (err) {
		printk("Failed to stat %s (%d)\n", path, err);
		return err;
	}

	if (dirent.type != FS_DIR_ENTRY_FILE) {
		return -EINVAL;
	}

	printk("File size: %zd\n", dirent.size);

	err = fs_open(&file, path);
	if (err) {
		printk("Failed to open %s (%d)\n", path, err);
		return err;
	}

	if (offset > 0) {
		fs_seek(&file, offset, FS_SEEK_SET);
	}

	while (count > 0) {
		ssize_t read;
		u8_t buf[16];
		int i;

		read = fs_read(&file, buf, min(count, sizeof(buf)));
		if (read <= 0) {
			break;
		}

		printk("%08X  ", (unsigned) offset);

		for (i = 0; i < read; i++) {
			printk("%02X ", buf[i]);
		}
		for (; i < sizeof(buf); i++) {
			printk("   ");
		}

		printk(" ");

		for (i = 0; i < read; i++) {
			printk("%c", buf[i] < 32 ||
			       buf[i] > 127 ? '.' : buf[i]);
		}

		printk("\n");

		offset += read;
		count -= read;
	}

	fs_close(&file);

	return 0;
}

static int cmd_write(int argc, char *argv[])
{
	char path[MAX_PATH_LEN];
	u8_t buf[BUF_CNT];
	u8_t buf_len;
	int arg_offset;
	struct fs_file_t file;
	off_t offset = -1;
	int err;

	if (argc < 3) {
		printk("Missing argument\n");
		return 0;
	}

	create_abs_path(argv[1], path, sizeof(path));

	if (!strcmp(argv[2], "-o")) {
		if (argc < 4) {
			printk("Missing argument\n");
			return 0;
		}

		offset = strtol(argv[3], NULL, 0);

		arg_offset = 4;
	} else {
		arg_offset = 2;
	}

	err = fs_open(&file, path);
	if (err) {
		printk("Failed to open %s (%d)\n", path, err);
		return err;
	}

	if (offset < 0) {
		err = fs_seek(&file, 0, FS_SEEK_END);
	} else {
		err = fs_seek(&file, offset, FS_SEEK_SET);
	}
	if (err) {
		printk("Failed to seek %s (%d)\n", path, err);
		fs_close(&file);
		return err;
	}

	buf_len = 0;
	while (arg_offset < argc) {
		buf[buf_len++] = strtol(argv[arg_offset++], NULL, 16);

		if ((buf_len == BUF_CNT) || (arg_offset == argc)) {
			err = fs_write(&file, buf, buf_len);
			if (err < 0) {
				printk("Failed to write %s (%d)\n", path, err);
				fs_close(&file);
				return err;
			}

			buf_len = 0;
		}
	}

	fs_close(&file);

	return 0;
}

static int cmd_ls(int argc, char *argv[])
{
	char path[MAX_PATH_LEN];
	struct fs_dir_t dir;
	int err;

	if (argc < 2) {
		strcpy(path, cwd);
	} else {
		create_abs_path(argv[1], path, sizeof(path));
	}

	err = fs_opendir(&dir, path);
	if (err) {
		printk("Unable to open %s (err %d)\n", path, err);
		return 0;
	}

	while (1) {
		struct fs_dirent entry;

		err = fs_readdir(&dir, &entry);
		if (err) {
			printk("Unable to read directory\n");
			break;
		}

		/* Check for end of directory listing */
		if (entry.name[0] == '\0') {
			break;
		}

		if (entry.type == FS_DIR_ENTRY_DIR) {
			printk("%s/\n", entry.name);
		} else {
			printk("%s\n", entry.name);
		}
	}

	fs_closedir(&dir);

	return 0;
}

static int cmd_pwd(int argc, char *argv[])
{
	printk("%s\n", cwd);
	return 0;
}

static int cmd_cd(int argc, char *argv[])
{
	char path[MAX_PATH_LEN];
	struct fs_dirent entry;
	int err;

	if (argc < 2) {
		strcpy(cwd, "/");
		return 0;
	}

	if (strcmp(argv[1], "..") == 0) {
		char *prev = strrchr(cwd, '/');

		if (!prev || prev == cwd) {
			strcpy(cwd, "/");
		} else {
			*prev = '\0';
		}

		/* No need to test that a parent exists */
		return 0;
	}

	create_abs_path(argv[1], path, sizeof(path));

	err = fs_stat(path, &entry);
	if (err) {
		printk("%s doesn't exist\n", path);
		return 0;
	}

	if (entry.type != FS_DIR_ENTRY_DIR) {
		printk("%s is not a directory\n", path);
		return 0;
	}

	strcpy(cwd, path);

	return 0;
}

static int cmd_trunc(int argc, char *argv[])
{
	char path[MAX_PATH_LEN];
	struct fs_file_t file;
	int length;
	int err;

	if (argc < 2) {
		printk("Missing argument\n");
		return 0;
	}

	if (argv[1][0] == '/') {
		strncpy(path, argv[1], sizeof(path) - 1);
		path[MAX_PATH_LEN - 1] = '\0';
	} else {
		if (strcmp(cwd, "/") == 0) {
			snprintf(path, sizeof(path), "/%s", argv[1]);
		} else {
			snprintf(path, sizeof(path), "%s/%s", cwd, argv[1]);
		}
	}

	if (argc > 2) {
		length = strtol(argv[2], NULL, 0);
	} else {
		length = 0;
	}

	err = fs_open(&file, path);
	if (err) {
		printk("Failed to open %s (%d)\n", path, err);
		return err;
	}

	err = fs_truncate(&file, length);
	if (err) {
		printk("Failed to truncate %s (%d)\n", path, err);
		fs_close(&file);
		return err;
	}

	fs_close(&file);

	return 0;
}

struct shell_cmd fs_commands[] = {
	{ "ls",    cmd_ls,    "List files in current directory" },
	{ "cd",    cmd_cd,    "Change working directory" },
	{ "pwd",   cmd_pwd,   "Print current working directory" },
	{ "mkdir", cmd_mkdir, "Create directory" },
	{ "rm",    cmd_rm,    "Remove file"},
	{ "read",  cmd_read,  "Read from file" },
	{ "write", cmd_write, "Write to file" },
	{ "trunc", cmd_trunc, "Truncate file" },
	{ NULL, NULL }
};


SHELL_REGISTER("fs", fs_commands);
