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

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

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

void prefetch(unsigned char *sha1)
{
}

static struct packed_git *packs = NULL;

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);
	while ((de = readdir(dir)) != NULL) {
		int namelen = strlen(de->d_name);
		if (namelen != 50 || 
		    strcmp(de->d_name + namelen - 5, ".pack"))
			continue;
		get_sha1_hex(de->d_name + 5, sha1);
		setup_index(sha1);
	}
	return 0;
}

static int copy_file(const char *source, const char *dest, const char *hex)
{
	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) {
			fprintf(stderr, "does not exist %s\n", source);
			return -1;
		}
	}
	if (use_symlink && !symlink(source, dest)) {
		pull_say("symlink %s\n", hex);
		return 0;
	}
	if (use_filecopy) {
		int ifd, ofd, status;
		struct stat st;
		void *map;
		ifd = open(source, O_RDONLY);
		if (ifd < 0 || fstat(ifd, &st) < 0) {
			close(ifd);
			fprintf(stderr, "cannot open %s\n", source);
			return -1;
		}
		map = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, ifd, 0);
		close(ifd);
		if (map == MAP_FAILED) {
			fprintf(stderr, "cannot mmap %s\n", source);
			return -1;
		}
		ofd = open(dest, O_WRONLY | O_CREAT | O_EXCL, 0666);
		status = ((ofd < 0) ||
			  (write(ofd, map, st.st_size) != st.st_size));
		munmap(map, st.st_size);
		close(ofd);
		if (status)
			fprintf(stderr, "cannot write %s\n", dest);
		else
			pull_say("copy %s\n", hex);
		return status;
	}
	fprintf(stderr, "failed to copy %s with given copy methods.\n", hex);
	return -1;
}

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));
	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));
	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);
	const 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);
}

int fetch(unsigned char *sha1)
{
	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);
		fprintf(stderr, "cannot open %s\n", filename);
		return -1;
	}
	if (read(ifd, hex, 40) != 40 || get_sha1_hex(hex, sha1)) {
		close(ifd);
		fprintf(stderr, "cannot read from %s\n", filename);
		return -1;
	}
	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] [-d] [-v] [-w filename] [--recover] [-l] [-s] [-n] 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, char **argv)
{
	char *commit_id;
	int arg = 1;

	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
			usage(local_pull_usage);
		arg++;
	}
	if (argc < arg + 2)
		usage(local_pull_usage);
	commit_id = argv[arg];
	path = argv[arg + 1];

	if (pull(commit_id))
		return 1;

	return 0;
}
