/*
 * test_icount.c
 * 
 * Copyright (C) 1997 Theodore Ts'o.
 *
 * %Begin-Header%
 * This file may be redistributed under the terms of the GNU Public
 * License.
 * %End-Header%
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#ifdef HAVE_GETOPT_H
#include <getopt.h>
#endif
#include <fcntl.h>

#include <ext2fs/ext2_fs.h>

#include <et/com_err.h>
#include <ss/ss.h>
#include <ext2fs/ext2fs.h>
#include <ext2fs/irel.h>
#include <ext2fs/brel.h>

extern ss_request_table test_cmds;

#include "test_icount.h"

ext2_filsys test_fs;
ext2_icount_t test_icount;

/*
 * Helper function which assures that the icount structure is valid
 */
static int check_icount(char *request)
{
	if (test_icount)
		return 0;
	com_err(request, 0, "The icount structure must be allocated.");
	return 1;
}

/*
 * Helper function which parses an inode number.
 */
static int parse_inode(const char *request, const char *desc,
		       const char *str, ext2_ino_t *ino)
{
	char *tmp;
	
	*ino = strtoul(str, &tmp, 0);
	if (*tmp) {
		com_err(request, 0, "Bad %s - %s", desc, str);
		return 1;
	}
	return 0;
}

void do_create_icount(int argc, char **argv)
{
	errcode_t	retval;
	char		*progname;
	int		flags = 0;
	ext2_ino_t	size = 5;

	progname = *argv;
	argv++; argc --;

	if (argc && !strcmp("-i", *argv)) {
		flags |= EXT2_ICOUNT_OPT_INCREMENT;
		argv++; argc--;
	}
	if (argc) {
		if (parse_inode(progname, "icount size", argv[0], &size))
			return;
		argv++; argc--;
	}
#if 0
	printf("Creating icount... flags=%d, size=%d\n", flags, (int) size);
#endif
	retval = ext2fs_create_icount(test_fs, flags, (int) size,
				      &test_icount);
	if (retval) {
		com_err(progname, retval, "while creating icount");
		return;
	}
}

void do_free_icount(int argc, char **argv)
{
	if (check_icount(argv[0]))
		return;

	ext2fs_free_icount(test_icount);
	test_icount = 0;
}

void do_fetch(int argc, char **argv)
{
	const char	*usage = "usage: %s inode\n";
	errcode_t	retval;
	ext2_ino_t	ino;
	__u16		count;
	
	if (argc < 2) {
		printf(usage, argv[0]);
		return;
	}
	if (check_icount(argv[0]))
		return;
	if (parse_inode(argv[0], "inode", argv[1], &ino))
		return;
	retval = ext2fs_icount_fetch(test_icount, ino, &count);
	if (retval) {
		com_err(argv[0], retval, "while calling ext2fs_icount_fetch");
		return;
	}
	printf("Count is %u\n", count);
}

void do_increment(int argc, char **argv)
{
	const char	*usage = "usage: %s inode\n";
	errcode_t	retval;
	ext2_ino_t	ino;
	__u16		count;
	
	if (argc < 2) {
		printf(usage, argv[0]);
		return;
	}
	if (check_icount(argv[0]))
		return;
	if (parse_inode(argv[0], "inode", argv[1], &ino))
		return;
	retval = ext2fs_icount_increment(test_icount, ino, &count);
	if (retval) {
		com_err(argv[0], retval,
			"while calling ext2fs_icount_increment");
		return;
	}
	printf("Count is now %u\n", count);
}

void do_decrement(int argc, char **argv)
{
	const char	*usage = "usage: %s inode\n";
	errcode_t	retval;
	ext2_ino_t	ino;
	__u16		count;
	
	if (argc < 2) {
		printf(usage, argv[0]);
		return;
	}
	if (check_icount(argv[0]))
		return;
	if (parse_inode(argv[0], "inode", argv[1], &ino))
		return;
	retval = ext2fs_icount_decrement(test_icount, ino, &count);
	if (retval) {
		com_err(argv[0], retval,
			"while calling ext2fs_icount_decrement");
		return;
	}
	printf("Count is now %u\n", count);
}

void do_store(int argc, char **argv)
{
	const char	*usage = "usage: %s inode count\n";
	errcode_t	retval;
	ext2_ino_t	ino;
	ext2_ino_t	count;
	
	if (argc < 3) {
		printf(usage, argv[0]);
		return;
	}
	if (check_icount(argv[0]))
		return;
	if (parse_inode(argv[0], "inode", argv[1], &ino))
		return;
	if (parse_inode(argv[0], "count", argv[2], &count))
		return;
	if (count > 65535) {
		printf("Count too large.\n");
		return;
	}
	retval = ext2fs_icount_store(test_icount, ino, (__u16) count);
	if (retval) {
		com_err(argv[0], retval,
			"while calling ext2fs_icount_store");
		return;
	}
}

void do_dump(int argc, char **argv)
{
	errcode_t	retval;
	ext2_ino_t	i;
	__u16		count;

	if (check_icount(argv[0]))
		return;
	for (i=1; i <= test_fs->super->s_inodes_count; i++) {
		retval = ext2fs_icount_fetch(test_icount, i, &count);
		if (retval) {
			com_err(argv[0], retval,
				"while fetching icount for %lu", (unsigned long)i);
			return;
		}
		if (count)
			printf("%lu: %u\n", (unsigned long)i, count);
	}
}

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

	if (check_icount(argv[0]))
		return;
	retval = ext2fs_icount_validate(test_icount, stdout);
	if (retval) {
		com_err(argv[0], retval, "while validating icount structure");
		return;
	}
	printf("Icount structure successfully validated\n");
}

void do_get_size(int argc, char **argv)
{
	ext2_ino_t	size;

	if (check_icount(argv[0]))
		return;
	size = ext2fs_get_icount_size(test_icount);
	printf("Size of icount is: %lu\n", (unsigned long)size);
}

static int source_file(const char *cmd_file, int sci_idx)
{
	FILE		*f;
	char		buf[256];
	char		*cp;
	int		exit_status = 0;
	int		retval;
	int 		noecho;

	if (strcmp(cmd_file, "-") == 0)
		f = stdin;
	else {
		f = fopen(cmd_file, "r");
		if (!f) {
			perror(cmd_file);
			exit(1);
		}
	}
	setbuf(stdout, NULL);
	setbuf(stderr, NULL);
	while (!feof(f)) {
		if (fgets(buf, sizeof(buf), f) == NULL)
			break;
		if (buf[0] == '#')
			continue;
		noecho = 0;
		if (buf[0] == '-') {
			noecho = 1;
			buf[0] = ' ';
		}
		cp = strchr(buf, '\n');
		if (cp)
			*cp = 0;
		cp = strchr(buf, '\r');
		if (cp)
			*cp = 0;
		if (!noecho)
			printf("test_icount: %s\n", buf);
		retval = ss_execute_line(sci_idx, buf);
		if (retval) {
			ss_perror(sci_idx, retval, buf);
			exit_status++;
		}
	}
	return exit_status;
}

int main(int argc, char **argv)
{
	int		retval;
	int		sci_idx;
	const char	*usage = "Usage: test_icount [-R request] [-f cmd_file]";
	int		c;
	char		*request = 0;
	int		exit_status = 0;
	char		*cmd_file = 0;
	struct ext2_super_block param;
	
	initialize_ext2_error_table();

	/*
	 * Create a sample filesystem structure
	 */
	memset(&param, 0, sizeof(struct ext2_super_block));
	param.s_blocks_count = 80000;
	param.s_inodes_count = 20000;
	retval = ext2fs_initialize("/dev/null", 0, &param,
				   unix_io_manager, &test_fs);
	if (retval) {
		com_err("/dev/null", retval, "while setting up test fs");
		exit(1);
	}

	while ((c = getopt (argc, argv, "wR:f:")) != EOF) {
		switch (c) {
		case 'R':
			request = optarg;
			break;
		case 'f':
			cmd_file = optarg;
			break;
		default:
			com_err(argv[0], 0, usage);
			exit(1);
		}
	}
	sci_idx = ss_create_invocation("test_icount", "0.0", (char *) NULL,
				       &test_cmds, &retval);
	if (retval) {
		ss_perror(sci_idx, retval, "creating invocation");
		exit(1);
	}

	(void) ss_add_request_table (sci_idx, &ss_std_requests, 1, &retval);
	if (retval) {
		ss_perror(sci_idx, retval, "adding standard requests");
		exit (1);
	}
	if (request) {
		retval = 0;
		retval = ss_execute_line(sci_idx, request);
		if (retval) {
			ss_perror(sci_idx, retval, request);
			exit_status++;
		}
	} else if (cmd_file) {
		exit_status = source_file(cmd_file, sci_idx);
	} else {
		ss_listen(sci_idx);
	}

	return(exit_status);
}
