/*
 * extent_inode.c --- direct extent tree manipulation
 *
 * Copyright (C) 2012 Theodore Ts'o.  This file may be redistributed
 * under the terms of the GNU Public License.
 */

#include "config.h"
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <time.h>
#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif
#include <sys/types.h>
#ifdef HAVE_GETOPT_H
#include <getopt.h>
#else
extern int optind;
extern char *optarg;
#endif

#include "debugfs.h"

static ext2_ino_t	current_ino;
static ext2_extent_handle_t current_handle;

static void dbg_print_extent(char *desc, struct ext2fs_extent *extent)
{
	if (desc)
		printf("%s: ", desc);
	printf("extent: lblk %llu--%llu, len %u, pblk %llu, flags: ",
	       extent->e_lblk, extent->e_lblk + extent->e_len - 1,
	       extent->e_len, extent->e_pblk);
	if (extent->e_flags & EXT2_EXTENT_FLAGS_LEAF)
		fputs("LEAF ", stdout);
	if (extent->e_flags & EXT2_EXTENT_FLAGS_UNINIT)
		fputs("UNINIT ", stdout);
	if (extent->e_flags & EXT2_EXTENT_FLAGS_SECOND_VISIT)
		fputs("2ND_VISIT ", stdout);
	if (!extent->e_flags)
		fputs("(none)", stdout);
	fputc('\n', stdout);

}

static int common_extent_args_process(int argc, char *argv[], int min_argc,
				      int max_argc, const char *cmd,
				      const char *usage, int flags)
{
	if (common_args_process(argc, argv, min_argc, max_argc, cmd,
				usage, flags))
		return 1;

	if (!current_handle) {
		com_err(cmd, 0, "Extent handle not open");
		return 1;
	}
	return 0;
}

static char *orig_prompt, *extent_prompt;

void do_extent_open(int argc, char *argv[])
{
	ext2_ino_t	inode;
	int		ret;
	errcode_t	retval;
	char		*cp;

	if (check_fs_open(argv[0]))
		return;

	if (argc == 1) {
		if (current_ino)
			printf("Current inode is %d\n", current_ino);
		else
			printf("No current inode\n");
		return;
	}

	if (common_inode_args_process(argc, argv, &inode, 0))
		return;

	current_ino = 0;

	retval = ext2fs_extent_open(current_fs, inode, &current_handle);
	if (retval) {
		com_err(argv[1], retval, "while opening extent handle");
		return;
	}

	current_ino = inode;

	orig_prompt = ss_get_prompt(sci_idx);
	extent_prompt = malloc(strlen(orig_prompt) + 32);
	strcpy(extent_prompt, orig_prompt);
	cp = strchr(extent_prompt, ':');
	if (cp)
		*cp = 0;
	sprintf(extent_prompt + strlen(extent_prompt), " (extent ino %d): ",
		current_ino);
	ss_add_request_table(sci_idx, &extent_cmds, 1, &ret);
	ss_set_prompt(sci_idx, extent_prompt);
	return;
}

void do_extent_close(int argc, char *argv[])
{
	int ret;

	if (common_args_process(argc, argv, 1, 1,
				"extent_close", "", 0))
		return;

	if (!current_handle) {
		com_err(argv[0], 0, "Extent handle not open");
		return;
	}

	ext2fs_extent_free(current_handle);
	current_handle = NULL;
	current_ino = 0;
	ss_delete_request_table(sci_idx, &extent_cmds, &ret);
	ss_set_prompt(sci_idx, orig_prompt);
	free(extent_prompt);
	extent_prompt = NULL;
}

static void generic_goto_node(const char *my_name, int argc,
			      char **argv, int op)
{
	struct ext2fs_extent	extent;
	errcode_t		retval;

	if (my_name && common_args_process(argc, argv, 1, 1,
					   my_name, "", 0))
		return;

	if (!current_handle) {
		com_err(argv[0], 0, "Extent handle not open");
		return;
	}

	retval = ext2fs_extent_get(current_handle, op, &extent);
	if (retval) {
		com_err(argv[0], retval, 0);
		return;
	}
	dbg_print_extent(0, &extent);
}

void do_current_node(int argc, char *argv[])
{
	generic_goto_node("current_node", argc, argv, EXT2_EXTENT_CURRENT);
}

void do_root_node(int argc, char *argv[])
{
	generic_goto_node("root_node", argc, argv, EXT2_EXTENT_ROOT);
}

void do_last_leaf(int argc, char *argv[])
{
	generic_goto_node("last_leaf", argc, argv, EXT2_EXTENT_LAST_LEAF);
}

void do_first_sib(int argc, char *argv[])
{
	generic_goto_node("first_sib", argc, argv, EXT2_EXTENT_FIRST_SIB);
}

void do_last_sib(int argc, char *argv[])
{
	generic_goto_node("next_sib", argc, argv, EXT2_EXTENT_LAST_SIB);
}

void do_next_sib(int argc, char *argv[])
{
	generic_goto_node("next_sib", argc, argv, EXT2_EXTENT_NEXT_SIB);
}

void do_prev_sib(int argc, char *argv[])
{
	generic_goto_node("prev_sib", argc, argv, EXT2_EXTENT_PREV_SIB);
}

void do_next_leaf(int argc, char *argv[])
{
	generic_goto_node("next_leaf", argc, argv, EXT2_EXTENT_NEXT_LEAF);
}

void do_prev_leaf(int argc, char *argv[])
{
	generic_goto_node("prev_leaf", argc, argv, EXT2_EXTENT_PREV_LEAF);
}

void do_next(int argc, char *argv[])
{
	generic_goto_node("next", argc, argv, EXT2_EXTENT_NEXT);
}

void do_prev(int argc, char *argv[])
{
	generic_goto_node("prev", argc, argv, EXT2_EXTENT_PREV);
}

void do_up(int argc, char *argv[])
{
	generic_goto_node("up", argc, argv, EXT2_EXTENT_UP);
}

void do_down(int argc, char *argv[])
{
	generic_goto_node("down", argc, argv, EXT2_EXTENT_DOWN);
}

void do_delete_node(int argc, char *argv[])
{
	struct ext2fs_extent extent;
	errcode_t	retval;

	if (common_extent_args_process(argc, argv, 1, 1, "delete_node",
				       "", CHECK_FS_RW | CHECK_FS_BITMAPS))
		return;

	retval = ext2fs_extent_delete(current_handle, 0);
	if (retval) {
		com_err(argv[0], retval, 0);
		return;
	}

	retval = ext2fs_extent_get(current_handle, EXT2_EXTENT_CURRENT,
				   &extent);
	if (retval)
		return;
	dbg_print_extent(0, &extent);
}

void do_replace_node(int argc, char *argv[])
{
	const char	*usage = "[--uninit] <lblk> <len> <pblk>";
	errcode_t	retval;
	struct ext2fs_extent extent;
	int err;

	if (common_extent_args_process(argc, argv, 3, 5, "replace_node",
				       usage, CHECK_FS_RW | CHECK_FS_BITMAPS))
		return;

	extent.e_flags = 0;

	if (!strcmp(argv[1], "--uninit")) {
		argc--;
		argv++;
		extent.e_flags |= EXT2_EXTENT_FLAGS_UNINIT;
	}

	if (argc != 4) {
		fprintf(stderr, "Usage: %s %s\n", argv[0], usage);
		return;
	}

	err = strtoblk(argv[0], argv[1], "logical block", &extent.e_lblk);
	if (err)
		return;

	extent.e_len = parse_ulong(argv[2], argv[0], "length", &err);
	if (err)
		return;

	err = strtoblk(argv[0], argv[3], "physical block", &extent.e_pblk);
	if (err)
		return;

	retval = ext2fs_extent_replace(current_handle, 0, &extent);
	if (retval) {
		com_err(argv[0], retval, 0);
		return;
	}
	generic_goto_node(NULL, argc, argv, EXT2_EXTENT_CURRENT);
}

void do_split_node(int argc, char *argv[])
{
	errcode_t	retval;

	if (common_extent_args_process(argc, argv, 1, 1, "split_node",
				       "", CHECK_FS_RW | CHECK_FS_BITMAPS))
		return;

	retval = ext2fs_extent_node_split(current_handle);
	if (retval) {
		com_err(argv[0], retval, 0);
		return;
	}
	generic_goto_node(NULL, argc, argv, EXT2_EXTENT_CURRENT);
}

void do_insert_node(int argc, char *argv[])
{
	const char	*usage = "[--after] [--uninit] <lblk> <len> <pblk>";
	errcode_t	retval;
	struct ext2fs_extent extent;
	char *cmd;
	int err;
	int flags = 0;

	if (common_extent_args_process(argc, argv, 3, 6, "insert_node",
				       usage, CHECK_FS_RW | CHECK_FS_BITMAPS))
		return;

	cmd = argv[0];

	extent.e_flags = 0;

	while (argc > 2) {
		if (!strcmp(argv[1], "--after")) {
			argc--;
			argv++;
			flags |= EXT2_EXTENT_INSERT_AFTER;
			continue;
		}
		if (!strcmp(argv[1], "--uninit")) {
			argc--;
			argv++;
			extent.e_flags |= EXT2_EXTENT_FLAGS_UNINIT;
			continue;
		}
		break;
	}

	if (argc != 4) {
		fprintf(stderr, "usage: %s %s\n", cmd, usage);
		return;
	}

	err = strtoblk(cmd, argv[1], "logical block", &extent.e_lblk);
	if (err)
		return;

	extent.e_len = parse_ulong(argv[2], cmd, "length", &err);
	if (err)
		return;

	err = strtoblk(cmd, argv[3], "physical block", &extent.e_pblk);
	if (err)
		return;

	retval = ext2fs_extent_insert(current_handle, flags, &extent);
	if (retval) {
		com_err(cmd, retval, 0);
		return;
	}
	generic_goto_node(NULL, argc, argv, EXT2_EXTENT_CURRENT);
}

void do_set_bmap(int argc, char **argv)
{
	const char	*usage = "[--uninit] <lblk> <pblk>";
	struct ext2fs_extent extent;
	errcode_t	retval;
	blk64_t		logical;
	blk64_t		physical;
	char		*cmd = argv[0];
	int		flags = 0;
	int		err;

	if (common_extent_args_process(argc, argv, 3, 5, "set_bmap",
				       usage, CHECK_FS_RW | CHECK_FS_BITMAPS))
		return;

	if (argc > 2 && !strcmp(argv[1], "--uninit")) {
		argc--;
		argv++;
		flags |= EXT2_EXTENT_SET_BMAP_UNINIT;
	}

	if (argc != 3) {
		fprintf(stderr, "Usage: %s %s\n", cmd, usage);
		return;
	}

	err = strtoblk(cmd, argv[1], "logical block", &logical);
	if (err)
		return;

	err = strtoblk(cmd, argv[2], "physical block", &physical);
	if (err)
		return;

	retval = ext2fs_extent_set_bmap(current_handle, logical,
					physical, flags);
	if (retval) {
		com_err(cmd, retval, 0);
		return;
	}

	retval = ext2fs_extent_get(current_handle, EXT2_EXTENT_CURRENT,
				   &extent);
	if (retval)
		return;
	dbg_print_extent(0, &extent);
}

void do_print_all(int argc, char **argv)
{
	const char	*usage = "[--leaf-only|--reverse|--reverse-leaf]";
	struct ext2fs_extent	extent;
	errcode_t		retval;
	errcode_t		end_err = EXT2_ET_EXTENT_NO_NEXT;
	int			op = EXT2_EXTENT_NEXT;
	int			first_op = EXT2_EXTENT_ROOT;


	if (common_extent_args_process(argc, argv, 1, 2, "print_all",
				       usage, 0))
		return;

	if (argc == 2) {
		if (!strcmp(argv[1], "--leaf-only"))
			op = EXT2_EXTENT_NEXT_LEAF;
		else if (!strcmp(argv[1], "--reverse")) {
			op = EXT2_EXTENT_PREV;
			first_op = EXT2_EXTENT_LAST_LEAF;
			end_err = EXT2_ET_EXTENT_NO_PREV;
		} else if (!strcmp(argv[1], "--reverse-leaf")) {
			op = EXT2_EXTENT_PREV_LEAF;
			first_op = EXT2_EXTENT_LAST_LEAF;
			end_err = EXT2_ET_EXTENT_NO_PREV;
		} else {
			fprintf(stderr, "Usage: %s %s\n", argv[0], usage);
			return;
		}
	}

	retval = ext2fs_extent_get(current_handle, first_op, &extent);
	if (retval) {
		com_err(argv[0], retval, 0);
		return;
	}
	dbg_print_extent(0, &extent);

	while (1) {
		retval = ext2fs_extent_get(current_handle, op, &extent);
		if (retval == end_err)
			break;

		if (retval) {
			com_err(argv[0], retval, 0);
			return;
		}
		dbg_print_extent(0, &extent);
	}
}

void do_fix_parents(int argc, char **argv)
{
	errcode_t		retval;

	if (common_extent_args_process(argc, argv, 1, 1, "fix_parents", "",
				       CHECK_FS_RW))
		return;

	retval = ext2fs_extent_fix_parents(current_handle);
	if (retval) {
		com_err(argv[0], retval, 0);
		return;
	}
}

void do_info(int argc, char **argv)
{
	struct ext2fs_extent	extent;
	struct ext2_extent_info	info;
	errcode_t		retval;

	if (common_extent_args_process(argc, argv, 1, 1, "info", "", 0))
		return;

	retval = ext2fs_extent_get_info(current_handle, &info);
	if (retval) {
		com_err(argv[0], retval, 0);
		return;
	}

	retval = ext2fs_extent_get(current_handle,
				   EXT2_EXTENT_CURRENT, &extent);
	if (retval) {
		com_err(argv[0], retval, 0);
		return;
	}

	dbg_print_extent(0, &extent);

	printf("Current handle location: %d/%d (max: %d, bytes %d), level %d/%d\n",
	       info.curr_entry, info.num_entries, info.max_entries,
	       info.bytes_avail, info.curr_level, info.max_depth);
	printf("\tmax lblk: %llu, max pblk: %llu\n", info.max_lblk,
	       info.max_pblk);
	printf("\tmax_len: %u, max_uninit_len: %u\n", info.max_len,
	       info.max_uninit_len);
}

void do_goto_block(int argc, char **argv)
{
	errcode_t		retval;
	blk64_t			blk;
	int			level = 0, err;

	if (common_extent_args_process(argc, argv, 2, 3, "goto_block",
				       "block [level]", 0))
		return;

	if (strtoblk(argv[0], argv[1], NULL, &blk))
		return;

	if (argc == 3) {
		level = parse_ulong(argv[2], argv[0], "level", &err);
		if (err)
			return;
	}

	retval = ext2fs_extent_goto2(current_handle, level, (blk64_t) blk);

	if (retval) {
		com_err(argv[0], retval,
			"while trying to go to block %llu, level %d",
			(unsigned long long) blk, level);
		return;
	}

	generic_goto_node(NULL, argc, argv, EXT2_EXTENT_CURRENT);
}
