/*
 * Copyright (C) 2005 Junio C Hamano
 */
#include "cache.h"
#include "commit.h"
#include "fetch.h"

static int use_link;
static int use_symlink;
static int use_filecopy = 1;
static int commits_on_stdin;

static const char *path; /* "Remote" git repository */

void prefetch(unsigned char *sha1)
{
}

static struct packed_git *packs;

static void setup_index(unsigned char *sha1)
{
	struct packed_git *new_pack;
	char filename[PATH_MAX];
	strcpy(filename, path);
	strcat(filename, "/objects/pack/pack-");
	strcat(filename, sha1_to_hex(sha1));
	strcat(filename, ".idx");
	new_pack = parse_pack_index_file(sha1, filename);
	new_pack->next = packs;
	packs = new_pack;
}

static int setup_indices(void)
{
	DIR *dir;
	struct dirent *de;
	char filename[PATH_MAX];
	unsigned char sha1[20];
	sprintf(filename, "%s/objects/pack/", path);
	dir = opendir(filename);
	if (!dir)
		return -1;
	while ((de = readdir(dir)) != NULL) {
		int namelen = strlen(de->d_name);
		if (namelen != 50 ||
		    !has_extension(de->d_name, ".pack"))
			continue;
		get_sha1_hex(de->d_name + 5, sha1);
		setup_index(sha1);
	}
	closedir(dir);
	return 0;
}

static int copy_file(const char *source, char *dest, const char *hex,
		     int warn_if_not_exists)
{
	safe_create_leading_directories(dest);
	if (use_link) {
		if (!link(source, dest)) {
			pull_say("link %s\n", hex);
			return 0;
		}
		/* If we got ENOENT there is no point continuing. */
		if (errno == ENOENT) {
			if (!warn_if_not_exists)
				return -1;
			return error("does not exist %s", source);
		}
	}
	if (use_symlink) {
		struct stat st;
		if (stat(source, &st)) {
			if (!warn_if_not_exists && errno == ENOENT)
				return -1;
			return error("cannot stat %s: %s", source,
				     strerror(errno));
		}
		if (!symlink(source, dest)) {
			pull_say("symlink %s\n", hex);
			return 0;
		}
	}
	if (use_filecopy) {
		int ifd, ofd, status = 0;

		ifd = open(source, O_RDONLY);
		if (ifd < 0) {
			if (!warn_if_not_exists && errno == ENOENT)
				return -1;
			return error("cannot open %s", source);
		}
		ofd = open(dest, O_WRONLY | O_CREAT | O_EXCL, 0666);
		if (ofd < 0) {
			close(ifd);
			return error("cannot open %s", dest);
		}
		status = copy_fd(ifd, ofd);
		close(ofd);
		if (status)
			return error("cannot write %s", dest);
		pull_say("copy %s\n", hex);
		return 0;
	}
	return error("failed to copy %s with given copy methods.", hex);
}

static int fetch_pack(const unsigned char *sha1)
{
	struct packed_git *target;
	char filename[PATH_MAX];
	if (setup_indices())
		return -1;
	target = find_sha1_pack(sha1, packs);
	if (!target)
		return error("Couldn't find %s: not separate or in any pack",
			     sha1_to_hex(sha1));
	if (get_verbosely) {
		fprintf(stderr, "Getting pack %s\n",
			sha1_to_hex(target->sha1));
		fprintf(stderr, " which contains %s\n",
			sha1_to_hex(sha1));
	}
	sprintf(filename, "%s/objects/pack/pack-%s.pack",
		path, sha1_to_hex(target->sha1));
	copy_file(filename, sha1_pack_name(target->sha1),
		  sha1_to_hex(target->sha1), 1);
	sprintf(filename, "%s/objects/pack/pack-%s.idx",
		path, sha1_to_hex(target->sha1));
	copy_file(filename, sha1_pack_index_name(target->sha1),
		  sha1_to_hex(target->sha1), 1);
	install_packed_git(target);
	return 0;
}

static int fetch_file(const unsigned char *sha1)
{
	static int object_name_start = -1;
	static char filename[PATH_MAX];
	char *hex = sha1_to_hex(sha1);
	char *dest_filename = sha1_file_name(sha1);

	if (object_name_start < 0) {
		strcpy(filename, path); /* e.g. git.git */
		strcat(filename, "/objects/");
		object_name_start = strlen(filename);
	}
	filename[object_name_start+0] = hex[0];
	filename[object_name_start+1] = hex[1];
	filename[object_name_start+2] = '/';
	strcpy(filename + object_name_start + 3, hex + 2);
	return copy_file(filename, dest_filename, hex, 0);
}

int fetch(unsigned char *sha1)
{
	if (has_sha1_file(sha1))
		return 0;
	else
		return fetch_file(sha1) && fetch_pack(sha1);
}

int fetch_ref(char *ref, unsigned char *sha1)
{
	static int ref_name_start = -1;
	static char filename[PATH_MAX];
	static char hex[41];
	int ifd;

	if (ref_name_start < 0) {
		sprintf(filename, "%s/refs/", path);
		ref_name_start = strlen(filename);
	}
	strcpy(filename + ref_name_start, ref);
	ifd = open(filename, O_RDONLY);
	if (ifd < 0) {
		close(ifd);
		return error("cannot open %s", filename);
	}
	if (read_in_full(ifd, hex, 40) != 40 || get_sha1_hex(hex, sha1)) {
		close(ifd);
		return error("cannot read from %s", filename);
	}
	close(ifd);
	pull_say("ref %s\n", sha1_to_hex(sha1));
	return 0;
}

static const char local_pull_usage[] =
"git-local-fetch [-c] [-t] [-a] [-v] [-w filename] [--recover] [-l] [-s] [-n] [--stdin] commit-id path";

/*
 * By default we only use file copy.
 * If -l is specified, a hard link is attempted.
 * If -s is specified, then a symlink is attempted.
 * If -n is _not_ specified, then a regular file-to-file copy is done.
 */
int main(int argc, const char **argv)
{
	int commits;
	const char **write_ref = NULL;
	char **commit_id;
	int arg = 1;

	setup_git_directory();
	git_config(git_default_config);

	while (arg < argc && argv[arg][0] == '-') {
		if (argv[arg][1] == 't')
			get_tree = 1;
		else if (argv[arg][1] == 'c')
			get_history = 1;
		else if (argv[arg][1] == 'a') {
			get_all = 1;
			get_tree = 1;
			get_history = 1;
		}
		else if (argv[arg][1] == 'l')
			use_link = 1;
		else if (argv[arg][1] == 's')
			use_symlink = 1;
		else if (argv[arg][1] == 'n')
			use_filecopy = 0;
		else if (argv[arg][1] == 'v')
			get_verbosely = 1;
		else if (argv[arg][1] == 'w')
			write_ref = &argv[++arg];
		else if (!strcmp(argv[arg], "--recover"))
			get_recover = 1;
		else if (!strcmp(argv[arg], "--stdin"))
			commits_on_stdin = 1;
		else
			usage(local_pull_usage);
		arg++;
	}
	if (argc < arg + 2 - commits_on_stdin)
		usage(local_pull_usage);
	if (commits_on_stdin) {
		commits = pull_targets_stdin(&commit_id, &write_ref);
	} else {
		commit_id = (char **) &argv[arg++];
		commits = 1;
	}
	path = argv[arg];

	if (pull(commits, commit_id, write_ref, path))
		return 1;

	if (commits_on_stdin)
		pull_targets_free(commits, commit_id, write_ref);

	return 0;
}
