#include "pull.h"

#include "cache.h"
#include "commit.h"
#include "tree.h"
#include "tag.h"
#include "blob.h"
#include "refs.h"

const char *write_ref = NULL;

const unsigned char *current_ref = NULL;

int get_tree = 0;
int get_history = 0;
int get_all = 0;
int get_verbosely = 0;
static unsigned char current_commit_sha1[20];

void pull_say(const char *fmt, const char *hex) 
{
	if (get_verbosely)
		fprintf(stderr, fmt, hex);
}

static void report_missing(const char *what, const unsigned char *missing)
{
	char missing_hex[41];

	strcpy(missing_hex, sha1_to_hex(missing));;
	fprintf(stderr,
		"Cannot obtain needed %s %s\nwhile processing commit %s.\n",
		what, missing_hex, sha1_to_hex(current_commit_sha1));
}

static int make_sure_we_have_it(const char *what, unsigned char *sha1)
{
	int status = 0;

	if (!has_sha1_file(sha1)) {
		status = fetch(sha1);
		if (status && what)
			report_missing(what, sha1);
	}
	return status;
}

static int process(unsigned char *sha1, const char *type);

static int process_tree(struct tree *tree)
{
	struct tree_entry_list *entries;

	if (parse_tree(tree))
		return -1;

	for (entries = tree->entries; entries; entries = entries->next) {
		if (process(entries->item.any->sha1,
			    entries->directory ? tree_type : blob_type))
			return -1;
	}
	return 0;
}

static int process_commit(struct commit *commit)
{
	if (parse_commit(commit))
		return -1;

	memcpy(current_commit_sha1, commit->object.sha1, 20);

	if (get_tree) {
		if (process(commit->tree->object.sha1, tree_type))
			return -1;
		if (!get_all)
			get_tree = 0;
	}
	if (get_history) {
		struct commit_list *parents = commit->parents;
		for (; parents; parents = parents->next) {
			if (has_sha1_file(parents->item->object.sha1))
				continue;
			if (process(parents->item->object.sha1,
				    commit_type))
				return -1;
		}
	}
	return 0;
}

static int process_tag(struct tag *tag)
{
	if (parse_tag(tag))
		return -1;
	return process(tag->tagged->sha1, NULL);
}

static struct object_list *process_queue = NULL;
static struct object_list **process_queue_end = &process_queue;

static int process_object(struct object *obj)
{
	if (obj->type == commit_type) {
		if (process_commit((struct commit *)obj))
			return -1;
		return 0;
	}
	if (obj->type == tree_type) {
		if (process_tree((struct tree *)obj))
			return -1;
		return 0;
	}
	if (obj->type == blob_type) {
		return 0;
	}
	if (obj->type == tag_type) {
		if (process_tag((struct tag *)obj))
			return -1;
		return 0;
	}
	return error("Unable to determine requirements "
		     "of type %s for %s",
		     obj->type, sha1_to_hex(obj->sha1));
}

static int process(unsigned char *sha1, const char *type)
{
	struct object *obj = lookup_object_type(sha1, type);
	if (has_sha1_file(sha1)) {
		parse_object(sha1);
		/* We already have it, so we should scan it now. */
		return process_object(obj);
	}
	if (object_list_contains(process_queue, obj))
		return 0;
	object_list_insert(obj, process_queue_end);
	process_queue_end = &(*process_queue_end)->next;

	//fprintf(stderr, "prefetch %s\n", sha1_to_hex(sha1));
	prefetch(sha1);
		
	return 0;
}

static int loop(void)
{
	while (process_queue) {
		struct object *obj = process_queue->item;
		/*
		fprintf(stderr, "%d objects to pull\n", 
			object_list_length(process_queue));
		*/
		process_queue = process_queue->next;
		if (!process_queue)
			process_queue_end = &process_queue;

		//fprintf(stderr, "fetch %s\n", sha1_to_hex(obj->sha1));
		
		if (make_sure_we_have_it(obj->type ? obj->type : "object", 
					 obj->sha1))
			return -1;
		if (!obj->type)
			parse_object(obj->sha1);
		if (process_object(obj))
			return -1;
	}
	return 0;
}

static int interpret_target(char *target, unsigned char *sha1)
{
	if (!get_sha1_hex(target, sha1))
		return 0;
	if (!check_ref_format(target)) {
		if (!fetch_ref(target, sha1)) {
			return 0;
		}
	}
	return -1;
}


int pull(char *target)
{
	unsigned char sha1[20];
	int fd = -1;

	if (write_ref && current_ref) {
		fd = lock_ref_sha1(write_ref, current_ref);
		if (fd < 0)
			return -1;
	}

	if (interpret_target(target, sha1))
		return error("Could not interpret %s as something to pull",
			     target);
	if (process(sha1, NULL))
		return -1;
	if (loop())
		return -1;
	
	if (write_ref) {
		if (current_ref) {
			write_ref_sha1(write_ref, fd, sha1);
		} else {
			write_ref_sha1_unlocked(write_ref, sha1);
		}
	}
	return 0;
}
