/*
 * Copyright (C) 2007 Oracle.  All rights reserved.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public
 * License v2 as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public
 * License along with this program; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 021110-1307, USA.
 */

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include "kerncompat.h"
#include "radix-tree.h"
#include "ctree.h"
#include "disk-io.h"
#include "print-tree.h"
#include "hash.h"
#include "transaction.h"

int keep_running = 1;
struct btrfs_super_block super;
static u64 dir_oid = 0;
static u64 file_oid = 33778;

static int find_num(struct radix_tree_root *root, unsigned long *num_ret,
		     int exists)
{
	unsigned long num = rand();
	unsigned long res[2];
	int ret;

again:
	ret = radix_tree_gang_lookup(root, (void **)res, num, 2);
	if (exists) {
		if (ret == 0)
			return -1;
		num = res[0];
	} else if (ret != 0 && num == res[0]) {
		num++;
		if (ret > 1 && num == res[1]) {
			num++;
			goto again;
		}
	}
	*num_ret = num;
	return 0;
}

static void initial_inode_init(struct btrfs_root *root,
			       struct btrfs_inode_item *inode_item)
{
	memset(inode_item, 0, sizeof(*inode_item));
	btrfs_set_inode_generation(inode_item, root->fs_info->generation);
	btrfs_set_inode_mode(inode_item, S_IFREG | 0700);
}

static int ins_one(struct btrfs_trans_handle *trans, struct btrfs_root *root,
		   struct radix_tree_root *radix)
{
	int ret;
	char buf[128];
	unsigned long oid;
	u64 objectid;
	struct btrfs_path path;
	struct btrfs_key inode_map;
	struct btrfs_inode_item inode_item;

	find_num(radix, &oid, 0);
	sprintf(buf, "str-%lu", oid);

	ret = btrfs_find_free_objectid(trans, root, dir_oid + 1, &objectid);
	if (ret)
		goto error;

	inode_map.objectid = objectid;
	inode_map.flags = 0;
	btrfs_set_key_type(&inode_map, BTRFS_INODE_ITEM_KEY);
	inode_map.offset = 0;

	initial_inode_init(root, &inode_item);
	ret = btrfs_insert_inode(trans, root, objectid, &inode_item);
	if (ret)
		goto error;
	ret = btrfs_insert_dir_item(trans, root, buf, strlen(buf), dir_oid,
				    &inode_map, BTRFS_FT_UNKNOWN);
	if (ret)
		goto error;

	radix_tree_preload(GFP_KERNEL);
	ret = radix_tree_insert(radix, oid, (void *)oid);
	radix_tree_preload_end();
	if (ret)
		goto error;
	return ret;
error:
	if (ret != -EEXIST)
		goto fatal;

	/*
	 * if we got an EEXIST, it may be due to hash collision, double
	 * check
	 */
	btrfs_init_path(&path);
	ret = btrfs_lookup_dir_item(trans, root, &path, dir_oid, buf,
				    strlen(buf), 0);
	if (ret)
		goto fatal_release;
	if (!btrfs_match_dir_item_name(root, &path, buf, strlen(buf))) {
		struct btrfs_dir_item *di;
		char *found;
		u32 found_len;
		u64 myhash;
		u64 foundhash;

		di = btrfs_item_ptr(&path.nodes[0]->leaf, path.slots[0],
				    struct btrfs_dir_item);
		found = (char *)(di + 1);
		found_len = btrfs_dir_name_len(di);
		myhash = btrfs_name_hash(buf, strlen(buf));
		foundhash = btrfs_name_hash(found, found_len);
		if (myhash != foundhash)
			goto fatal_release;
		btrfs_release_path(root, &path);
		return 0;
	}
fatal_release:
	btrfs_release_path(root, &path);
fatal:
	printf("failed to insert %lu ret %d\n", oid, ret);
	return -1;
}

static int insert_dup(struct btrfs_trans_handle *trans, struct btrfs_root
		      *root, struct radix_tree_root *radix)
{
	int ret;
	char buf[128];
	unsigned long oid;
	struct btrfs_key key;

	ret = find_num(radix, &oid, 1);
	if (ret < 0)
		return 0;
	sprintf(buf, "str-%lu", oid);

	key.objectid = file_oid;
	key.flags = 0;
	btrfs_set_key_type(&key, BTRFS_INODE_ITEM_KEY);
	key.offset = 0;
	ret = btrfs_insert_dir_item(trans, root, buf, strlen(buf), dir_oid,
				    &key, BTRFS_FT_UNKNOWN);
	if (ret != -EEXIST) {
		printf("insert on %s gave us %d\n", buf, ret);
		return 1;
	}
	return 0;
}

static int del_dir_item(struct btrfs_trans_handle *trans,
			struct btrfs_root *root,
			struct radix_tree_root *radix,
			unsigned long radix_index,
			struct btrfs_path *path)
{
	int ret;
	unsigned long *ptr;
	u64 file_objectid;
	struct btrfs_dir_item *di;

	/* find the inode number of the file */
	di = btrfs_item_ptr(&path->nodes[0]->leaf, path->slots[0],
			    struct btrfs_dir_item);
	file_objectid = btrfs_disk_key_objectid(&di->location);

	/* delete the directory item */
	ret = btrfs_del_item(trans, root, path);
	if (ret)
		goto out_release;
	btrfs_release_path(root, path);

	/* delete the inode */
	btrfs_init_path(path);
	ret = btrfs_lookup_inode(trans, root, path, file_objectid, -1);
	if (ret)
		goto out_release;
	ret = btrfs_del_item(trans, root, path);
	if (ret)
		goto out_release;
	btrfs_release_path(root, path);

	if (root->fs_info->last_inode_alloc > file_objectid)
		root->fs_info->last_inode_alloc = file_objectid;
	ptr = radix_tree_delete(radix, radix_index);
	if (!ptr) {
		ret = -5555;
		goto out;
	}
	return 0;
out_release:
	btrfs_release_path(root, path);
out:
	printf("failed to delete %lu %d\n", radix_index, ret);
	return -1;
}

static int del_one(struct btrfs_trans_handle *trans, struct btrfs_root *root,
		   struct radix_tree_root *radix)
{
	int ret;
	char buf[128];
	unsigned long oid;
	struct btrfs_path path;

	ret = find_num(radix, &oid, 1);
	if (ret < 0)
		return 0;
	sprintf(buf, "str-%lu", oid);
	btrfs_init_path(&path);
	ret = btrfs_lookup_dir_item(trans, root, &path, dir_oid, buf,
				    strlen(buf), -1);
	if (ret)
		goto out_release;

	ret = del_dir_item(trans, root, radix, oid, &path);
	if (ret)
		goto out_release;
	return ret;
out_release:
	btrfs_release_path(root, &path);
	printf("failed to delete %lu %d\n", oid, ret);
	return -1;
}

static int lookup_item(struct btrfs_trans_handle *trans, struct btrfs_root
		       *root, struct radix_tree_root *radix)
{
	struct btrfs_path path;
	char buf[128];
	int ret;
	unsigned long oid;
	u64 objectid;
	struct btrfs_dir_item *di;

	ret = find_num(radix, &oid, 1);
	if (ret < 0)
		return 0;
	sprintf(buf, "str-%lu", oid);
	btrfs_init_path(&path);
	ret = btrfs_lookup_dir_item(trans, root, &path, dir_oid, buf,
				    strlen(buf), 0);
	if (!ret) {
		di = btrfs_item_ptr(&path.nodes[0]->leaf, path.slots[0],
				    struct btrfs_dir_item);
		objectid = btrfs_disk_key_objectid(&di->location);
	}
	btrfs_release_path(root, &path);
	if (ret) {
		printf("unable to find key %lu\n", oid);
		return -1;
	}
	return 0;
}

static int lookup_enoent(struct btrfs_trans_handle *trans, struct btrfs_root
			 *root, struct radix_tree_root *radix)
{
	struct btrfs_path path;
	char buf[128];
	int ret;
	unsigned long oid;

	ret = find_num(radix, &oid, 0);
	if (ret < 0)
		return 0;
	sprintf(buf, "str-%lu", oid);
	btrfs_init_path(&path);
	ret = btrfs_lookup_dir_item(trans, root, &path, dir_oid, buf,
				    strlen(buf), 0);
	btrfs_release_path(root, &path);
	if (!ret) {
		printf("able to find key that should not exist %lu\n", oid);
		return -1;
	}
	return 0;
}

static int empty_tree(struct btrfs_trans_handle *trans, struct btrfs_root
		      *root, struct radix_tree_root *radix, int nr)
{
	struct btrfs_path path;
	struct btrfs_key key;
	unsigned long found = 0;
	u32 found_len;
	int ret;
	int slot;
	int count = 0;
	char buf[128];
	struct btrfs_dir_item *di;

	key.offset = (u64)-1;
	key.flags = 0;
	btrfs_set_key_type(&key, BTRFS_DIR_ITEM_KEY);
	key.objectid = dir_oid;
	while(nr-- >= 0) {
		btrfs_init_path(&path);
		ret = btrfs_search_slot(trans, root, &key, &path, -1, 1);
		if (ret < 0) {
			btrfs_release_path(root, &path);
			return ret;
		}
		if (ret != 0) {
			if (path.slots[0] == 0) {
				btrfs_release_path(root, &path);
				break;
			}
			path.slots[0] -= 1;
		}
		slot = path.slots[0];
		di = btrfs_item_ptr(&path.nodes[0]->leaf, slot,
				    struct btrfs_dir_item);
		found_len = btrfs_dir_name_len(di);
		memcpy(buf, (char *)(di + 1), found_len);
		BUG_ON(found_len > 128);
		buf[found_len] = '\0';
		found = atoi(buf + 4);
		ret = del_dir_item(trans, root, radix, found, &path);
		count++;
		if (ret) {
			fprintf(stderr,
				"failed to remove %lu from tree\n",
				found);
			return -1;
		}
		if (!keep_running)
			break;
	}
	return 0;
	fprintf(stderr, "failed to delete from the radix %lu\n", found);
	return -1;
}

static int fill_tree(struct btrfs_trans_handle *trans, struct btrfs_root *root,
		     struct radix_tree_root *radix, int count)
{
	int i;
	int ret = 0;
	for (i = 0; i < count; i++) {
		ret = ins_one(trans, root, radix);
		if (ret) {
			fprintf(stderr, "fill failed\n");
			goto out;
		}
		if (i % 1000 == 0) {
			ret = btrfs_commit_transaction(trans, root, &super);
			if (ret) {
				fprintf(stderr, "fill commit failed\n");
				return ret;
			}
		}
		if (i && i % 10000 == 0) {
			printf("bigfill %d\n", i);
		}
		if (!keep_running)
			break;
	}
out:
	return ret;
}

static int bulk_op(struct btrfs_trans_handle *trans, struct btrfs_root *root,
		   struct radix_tree_root *radix)
{
	int ret;
	int nr = rand() % 5000;
	static int run_nr = 0;

	/* do the bulk op much less frequently */
	if (run_nr++ % 100)
		return 0;
	ret = empty_tree(trans, root, radix, nr);
	if (ret)
		return ret;
	ret = fill_tree(trans, root, radix, nr);
	if (ret)
		return ret;
	return 0;
}


int (*ops[])(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct
	     radix_tree_root *radix) =
	{ ins_one, insert_dup, del_one, lookup_item,
	  lookup_enoent, bulk_op };

void sigstopper(int ignored)
{
	keep_running = 0;
	fprintf(stderr, "caught exit signal, stopping\n");
}

int print_usage(void)
{
	printf("usage: tester [-ih] [-c count] [-f count]\n");
	printf("\t -c count -- iteration count after filling\n");
	printf("\t -f count -- run this many random inserts before starting\n");
	printf("\t -i       -- only do initial fill\n");
	printf("\t -h       -- this help text\n");
	exit(1);
}
int main(int ac, char **av)
{
	RADIX_TREE(radix, GFP_KERNEL);
	struct btrfs_root *root;
	int i;
	int ret;
	int count;
	int op;
	int iterations = 20000;
	int init_fill_count = 800000;
	int err = 0;
	int initial_only = 0;
	struct btrfs_trans_handle *trans;
	radix_tree_init();

	root = open_ctree(av[ac-1], &super, 0);

	if (!root) {
		fprintf(stderr, "Open ctree failed\n");
		return 1;
	}

	trans = btrfs_start_transaction(root, 1);

	dir_oid = btrfs_super_root_dir(&super);

	signal(SIGTERM, sigstopper);
	signal(SIGINT, sigstopper);

	for (i = 1 ; i < ac - 1; i++) {
		if (strcmp(av[i], "-i") == 0) {
			initial_only = 1;
		} else if (strcmp(av[i], "-c") == 0) {
			iterations = atoi(av[i+1]);
			i++;
		} else if (strcmp(av[i], "-f") == 0) {
			init_fill_count = atoi(av[i+1]);
			i++;
		} else {
			print_usage();
		}
	}
	printf("initial fill\n");
	ret = fill_tree(trans, root, &radix, init_fill_count);
	printf("starting run\n");
	if (ret) {
		err = ret;
		goto out;
	}
	if (initial_only == 1) {
		goto out;
	}
	for (i = 0; i < iterations; i++) {
		op = rand() % ARRAY_SIZE(ops);
		count = rand() % 128;
		if (i % 2000 == 0) {
			printf("%d\n", i);
			fflush(stdout);
		}
		if (i && i % 5000 == 0) {
			printf("open & close, root level %d nritems %d\n",
				btrfs_header_level(&root->node->node.header),
				btrfs_header_nritems(&root->node->node.header));
			close_ctree(root, &super);
			root = open_ctree("dbfile", &super, 0);

			if (!root) {
				fprintf(stderr, "Open ctree failed\n");
				return 1;
			}
		}
		while(count--) {
			ret = ops[op](trans, root, &radix);
			if (ret) {
				fprintf(stderr, "op %d failed %d:%d\n",
					op, i, iterations);
				btrfs_print_tree(root, root->node, 1);
				fprintf(stderr, "op %d failed %d:%d\n",
					op, i, iterations);
				err = ret;
				goto out;
			}
			if (ops[op] == bulk_op)
				break;
			if (keep_running == 0) {
				err = 0;
				goto out;
			}
		}
	}
out:
	close_ctree(root, &super);
	return err;
}

