/*
 * GIT - The information manager from hell
 *
 * Copyright (C) Linus Torvalds, 2005
 */
#include "cache.h"
#include "blob.h"
#include "tree.h"

static int line_termination = '\n';
#define LS_RECURSIVE 1
#define LS_TREE_ONLY 2
static int ls_options = 0;

static struct tree_entry_list root_entry;

static void prepare_root(unsigned char *sha1)
{
	unsigned char rsha[20];
	unsigned long size;
	void *buf;
	struct tree *root_tree;

	buf = read_object_with_reference(sha1, "tree", &size, rsha);
	free(buf);
	if (!buf)
		die("Could not read %s", sha1_to_hex(sha1));

	root_tree = lookup_tree(rsha);
	if (!root_tree)
		die("Could not read %s", sha1_to_hex(sha1));

	/* Prepare a fake entry */
	root_entry.directory = 1;
	root_entry.executable = root_entry.symlink = 0;
	root_entry.mode = S_IFDIR;
	root_entry.name = "";
	root_entry.item.tree = root_tree;
	root_entry.parent = NULL;
}

static int prepare_children(struct tree_entry_list *elem)
{
	if (!elem->directory)
		return -1;
	if (!elem->item.tree->object.parsed) {
		struct tree_entry_list *e;
		if (parse_tree(elem->item.tree))
			return -1;
		/* Set up the parent link */
		for (e = elem->item.tree->entries; e; e = e->next)
			e->parent = elem;
	}
	return 0;
}

static struct tree_entry_list *find_entry(const char *path, char *pathbuf)
{
	const char *next, *slash;
	int len;
	struct tree_entry_list *elem = &root_entry, *oldelem = NULL;

	*(pathbuf) = '\0';

	/* Find tree element, descending from root, that
	 * corresponds to the named path, lazily expanding
	 * the tree if possible.
	 */

	while (path) {
		/* The fact we still have path means that the caller
		 * wants us to make sure that elem at this point is a
		 * directory, and possibly descend into it.  Even what
		 * is left is just trailing slashes, we loop back to
		 * here, and this call to prepare_children() will
		 * catch elem not being a tree.  Nice.
		 */
		if (prepare_children(elem))
			return NULL;

		slash = strchr(path, '/');
		if (!slash) {
			len = strlen(path);
			next = NULL;
		}
		else {
			next = slash + 1;
			len = slash - path;
		}
		if (len) {
			if (oldelem) {
				pathbuf += sprintf(pathbuf, "%s/", oldelem->name);
			}

			/* (len == 0) if the original path was "drivers/char/"
			 * and we have run already two rounds, having elem
			 * pointing at the drivers/char directory.
			 */
			elem = elem->item.tree->entries;
			while (elem) {
				if ((strlen(elem->name) == len) &&
				    !strncmp(elem->name, path, len)) {
					/* found */
					break;
				}
				elem = elem->next;
			}
			if (!elem)
				return NULL;

			oldelem = elem;
		}
		path = next;
	}

	return elem;
}

static const char *entry_type(struct tree_entry_list *e)
{
	return (e->directory ? "tree" : "blob");
}

static const char *entry_hex(struct tree_entry_list *e)
{
	return sha1_to_hex(e->directory
			   ? e->item.tree->object.sha1
			   : e->item.blob->object.sha1);
}

/* forward declaration for mutually recursive routines */
static int show_entry(struct tree_entry_list *, int, char *pathbuf);

static int show_children(struct tree_entry_list *e, int level, char *pathbuf)
{
	int oldlen = strlen(pathbuf);

	if (e != &root_entry)
		sprintf(pathbuf + oldlen, "%s/", e->name);

	if (prepare_children(e))
		die("internal error: ls-tree show_children called with non tree");
	e = e->item.tree->entries;
	while (e) {
		show_entry(e, level, pathbuf);
		e = e->next;
	}

	pathbuf[oldlen] = '\0';

	return 0;
}

static int show_entry(struct tree_entry_list *e, int level, char *pathbuf)
{
	int err = 0; 

	if (e != &root_entry) {
		printf("%06o %s %s	%s%s", e->mode, entry_type(e),
		       entry_hex(e), pathbuf, e->name);
		putchar(line_termination);
	}

	if (e->directory) {
		/* If this is a directory, we have the following cases:
		 * (1) This is the top-level request (explicit path from the
		 *     command line, or "root" if there is no command line).
		 *  a. Without any flag.  We show direct children.  We do not 
		 *     recurse into them.
		 *  b. With -r.  We do recurse into children.
		 *  c. With -d.  We do not recurse into children.
		 * (2) We came here because our caller is either (1-a) or
		 *     (1-b).
		 *  a. Without any flag.  We do not show our children (which
		 *     are grandchildren for the original request).
		 *  b. With -r.  We continue to recurse into our children.
		 *  c. With -d.  We should not have come here to begin with.
		 */
		if (level == 0 && !(ls_options & LS_TREE_ONLY))
			/* case (1)-a and (1)-b */
			err = err | show_children(e, level+1, pathbuf);
		else if (level && ls_options & LS_RECURSIVE)
			/* case (2)-b */
			err = err | show_children(e, level+1, pathbuf);
	}
	return err;
}

static int list_one(const char *path)
{
	int err = 0;
	char pathbuf[MAXPATHLEN + 1];
	struct tree_entry_list *e = find_entry(path, pathbuf);
	if (!e) {
		/* traditionally ls-tree does not complain about
		 * missing path.  We may change this later to match
		 * what "/bin/ls -a" does, which is to complain.
		 */
		return err;
	}
	err = err | show_entry(e, 0, pathbuf);
	return err;
}

static int list(char **path)
{
	int i;
	int err = 0;
	for (i = 0; path[i]; i++)
		err = err | list_one(path[i]);
	return err;
}

static const char ls_tree_usage[] =
	"git-ls-tree [-d] [-r] [-z] <tree-ish> [path...]";

int main(int argc, char **argv)
{
	static char *path0[] = { "", NULL };
	char **path;
	unsigned char sha1[20];

	while (1 < argc && argv[1][0] == '-') {
		switch (argv[1][1]) {
		case 'z':
			line_termination = 0;
			break;
		case 'r':
			ls_options |= LS_RECURSIVE;
			break;
		case 'd':
			ls_options |= LS_TREE_ONLY;
			break;
		default:
			usage(ls_tree_usage);
		}
		argc--; argv++;
	}

	if (argc < 2)
		usage(ls_tree_usage);
	if (get_sha1(argv[1], sha1) < 0)
		usage(ls_tree_usage);

	path = (argc == 2) ? path0 : (argv + 2);
	prepare_root(sha1);
	if (list(path) < 0)
		die("list failed");
	return 0;
}
