/*
 * Copyright (c) 2005 Rene Scharfe
 */
#include <time.h>
#include "cache.h"

#define RECORDSIZE	(512)
#define BLOCKSIZE	(RECORDSIZE * 20)

#define TYPEFLAG_AUTO		'\0'
#define TYPEFLAG_REG		'0'
#define TYPEFLAG_LNK		'2'
#define TYPEFLAG_DIR		'5'
#define TYPEFLAG_GLOBAL_HEADER	'g'
#define TYPEFLAG_EXT_HEADER	'x'

#define EXT_HEADER_PATH		1
#define EXT_HEADER_LINKPATH	2

static const char tar_tree_usage[] = "git-tar-tree <key> [basedir]";

static char block[BLOCKSIZE];
static unsigned long offset;

static const char *basedir;
static time_t archive_time;

struct path_prefix {
	struct path_prefix *prev;
	const char *name;
};

/* tries hard to write, either succeeds or dies in the attempt */
static void reliable_write(void *buf, unsigned long size)
{
	while (size > 0) {
		long ret = write(1, buf, size);
		if (ret < 0) {
			if (errno == EAGAIN)
				continue;
			if (errno == EPIPE)
				exit(0);
			die("git-tar-tree: %s", strerror(errno));
		} else if (!ret) {
			die("git-tar-tree: disk full?");
		}
		size -= ret;
		buf += ret;
	}
}

/* writes out the whole block, but only if it is full */
static void write_if_needed(void)
{
	if (offset == BLOCKSIZE) {
		reliable_write(block, BLOCKSIZE);
		offset = 0;
	}
}

/* acquire the next record from the buffer; user must call write_if_needed() */
static char *get_record(void)
{
	char *p = block + offset;
	memset(p, 0, RECORDSIZE);
	offset += RECORDSIZE;
	return p;
}

/*
 * The end of tar archives is marked by 1024 nul bytes and after that
 * follows the rest of the block (if any).
 */
static void write_trailer(void)
{
	get_record();
	write_if_needed();
	get_record();
	write_if_needed();
	while (offset) {
		get_record();
		write_if_needed();
	}
}

/*
 * queues up writes, so that all our write(2) calls write exactly one
 * full block; pads writes to RECORDSIZE
 */
static void write_blocked(void *buf, unsigned long size)
{
	unsigned long tail;

	if (offset) {
		unsigned long chunk = BLOCKSIZE - offset;
		if (size < chunk)
			chunk = size;
		memcpy(block + offset, buf, chunk);
		size -= chunk;
		offset += chunk;
		buf += chunk;
		write_if_needed();
	}
	while (size >= BLOCKSIZE) {
		reliable_write(buf, BLOCKSIZE);
		size -= BLOCKSIZE;
		buf += BLOCKSIZE;
	}
	if (size) {
		memcpy(block + offset, buf, size);
		buf += size;
		offset += size;
	}
	tail = offset % RECORDSIZE;
	if (tail)  {
		memset(block + offset, 0, RECORDSIZE - tail);
		offset += RECORDSIZE - tail;
	}
	write_if_needed();
}

static void append_string(char **p, const char *s)
{
	unsigned int len = strlen(s);
	memcpy(*p, s, len);
	*p += len;
}

static void append_char(char **p, char c)
{
	**p = c;
	*p += 1;
}

static void append_path_prefix(char **buffer, struct path_prefix *prefix)
{
	if (!prefix)
		return;
	append_path_prefix(buffer, prefix->prev);
	append_string(buffer, prefix->name);
	append_char(buffer, '/');
}

static unsigned int path_prefix_len(struct path_prefix *prefix)
{
	if (!prefix)
		return 0;
	return path_prefix_len(prefix->prev) + strlen(prefix->name) + 1;
}

static void append_path(char **p, int is_dir, const char *basepath,
                        struct path_prefix *prefix, const char *path)
{
	if (basepath) {
		append_string(p, basepath);
		append_char(p, '/');
	}
	append_path_prefix(p, prefix);
	append_string(p, path);
	if (is_dir)
		append_char(p, '/');
}

static unsigned int path_len(int is_dir, const char *basepath,
                             struct path_prefix *prefix, const char *path)
{
	unsigned int len = 0;
	if (basepath)
		len += strlen(basepath) + 1;
	len += path_prefix_len(prefix) + strlen(path);
	if (is_dir)
		len++;
	return len;
}

static void append_extended_header_prefix(char **p, unsigned int size,
                                          const char *keyword)
{
	int len = sprintf(*p, "%u %s=", size, keyword);
	*p += len;
}

static unsigned int extended_header_len(const char *keyword,
                                        unsigned int valuelen)
{
	/* "%u %s=%s\n" */
	unsigned int len = 1 + 1 + strlen(keyword) + 1 + valuelen + 1;
	if (len > 9)
		len++;
	if (len > 99)
		len++;
	return len;
}

static void append_extended_header(char **p, const char *keyword,
                                   const char *value, unsigned int len)
{
	unsigned int size = extended_header_len(keyword, len);
	append_extended_header_prefix(p, size, keyword);
	memcpy(*p, value, len);
	*p += len;
	append_char(p, '\n');
}

static void write_header(const unsigned char *, char, const char *, struct path_prefix *,
                         const char *, unsigned int, void *, unsigned long);

/* stores a pax extended header directly in the block buffer */
static void write_extended_header(const char *headerfilename, int is_dir,
                                  unsigned int flags, const char *basepath,
                                  struct path_prefix *prefix,
                                  const char *path, unsigned int namelen,
                                  void *content, unsigned int contentsize)
{
	char *buffer, *p;
	unsigned int pathlen, size, linkpathlen = 0;

	size = pathlen = extended_header_len("path", namelen);
	if (flags & EXT_HEADER_LINKPATH) {
		linkpathlen = extended_header_len("linkpath", contentsize);
		size += linkpathlen;
	}
	write_header(NULL, TYPEFLAG_EXT_HEADER, NULL, NULL, headerfilename,
	             0100600, NULL, size);

	buffer = p = malloc(size);
	if (!buffer)
		die("git-tar-tree: %s", strerror(errno));
	append_extended_header_prefix(&p, pathlen, "path");
	append_path(&p, is_dir, basepath, prefix, path);
	append_char(&p, '\n');
	if (flags & EXT_HEADER_LINKPATH)
		append_extended_header(&p, "linkpath", content, contentsize);
	write_blocked(buffer, size);
	free(buffer);
}

static void write_global_extended_header(const unsigned char *sha1)
{
	char *p;
	unsigned int size;

	size = extended_header_len("comment", 40);
	write_header(NULL, TYPEFLAG_GLOBAL_HEADER, NULL, NULL,
	             "pax_global_header", 0100600, NULL, size);

	p = get_record();
	append_extended_header(&p, "comment", sha1_to_hex(sha1), 40);
	write_if_needed();
}

/* stores a ustar header directly in the block buffer */
static void write_header(const unsigned char *sha1, char typeflag, const char *basepath,
                         struct path_prefix *prefix, const char *path,
                         unsigned int mode, void *buffer, unsigned long size)
{
	unsigned int namelen; 
	char *header = NULL;
	unsigned int checksum = 0;
	int i;
	unsigned int ext_header = 0;

	if (typeflag == TYPEFLAG_AUTO) {
		if (S_ISDIR(mode))
			typeflag = TYPEFLAG_DIR;
		else if (S_ISLNK(mode))
			typeflag = TYPEFLAG_LNK;
		else
			typeflag = TYPEFLAG_REG;
	}

	namelen = path_len(S_ISDIR(mode), basepath, prefix, path);
	if (namelen > 100)
		ext_header |= EXT_HEADER_PATH;
	if (typeflag == TYPEFLAG_LNK && size > 100)
		ext_header |= EXT_HEADER_LINKPATH;

	/* the extended header must be written before the normal one */
	if (ext_header) {
		char headerfilename[51];
		sprintf(headerfilename, "%s.paxheader", sha1_to_hex(sha1));
		write_extended_header(headerfilename, S_ISDIR(mode),
		                      ext_header, basepath, prefix, path,
		                      namelen, buffer, size);
	}

	header = get_record();

	if (ext_header) {
		sprintf(header, "%s.data", sha1_to_hex(sha1));
	} else {
		char *p = header;
		append_path(&p, S_ISDIR(mode), basepath, prefix, path);
	}

	if (typeflag == TYPEFLAG_LNK) {
		if (ext_header & EXT_HEADER_LINKPATH) {
			sprintf(&header[157], "see %s.paxheader",
			        sha1_to_hex(sha1));
		} else {
			if (buffer)
				strncpy(&header[157], buffer, size);
		}
	}

	if (S_ISDIR(mode))
		mode |= 0755;	/* GIT doesn't store permissions of dirs */
	if (S_ISLNK(mode))
		mode |= 0777;   /* ... nor of symlinks */
	sprintf(&header[100], "%07o", mode & 07777);

	/* XXX: should we provide more meaningful info here? */
	sprintf(&header[108], "%07o", 0);	/* uid */
	sprintf(&header[116], "%07o", 0);	/* gid */
	strncpy(&header[265], "git", 31);	/* uname */
	strncpy(&header[297], "git", 31);	/* gname */

	if (S_ISDIR(mode) || S_ISLNK(mode))
		size = 0;
	sprintf(&header[124], "%011lo", size);
	sprintf(&header[136], "%011lo", archive_time);

	header[156] = typeflag;

	memcpy(&header[257], "ustar", 6);
	memcpy(&header[263], "00", 2);

	sprintf(&header[329], "%07o", 0);	/* devmajor */
	sprintf(&header[337], "%07o", 0);	/* devminor */

	memset(&header[148], ' ', 8);
	for (i = 0; i < RECORDSIZE; i++)
		checksum += header[i];
	sprintf(&header[148], "%07o", checksum & 0x1fffff);

	write_if_needed();
}

static void traverse_tree(void *buffer, unsigned long size,
			  struct path_prefix *prefix)
{
	struct path_prefix this_prefix;
	this_prefix.prev = prefix;

	while (size) {
		int namelen = strlen(buffer)+1;
		void *eltbuf;
		char elttype[20];
		unsigned long eltsize;
		unsigned char *sha1 = buffer + namelen;
		char *path = strchr(buffer, ' ') + 1;
		unsigned int mode;

		if (size < namelen + 20 || sscanf(buffer, "%o", &mode) != 1)
			die("corrupt 'tree' file");
		if (S_ISDIR(mode) || S_ISREG(mode))
			mode |= (mode & 0100) ? 0777 : 0666;
		buffer = sha1 + 20;
		size -= namelen + 20;

		eltbuf = read_sha1_file(sha1, elttype, &eltsize);
		if (!eltbuf)
			die("cannot read %s", sha1_to_hex(sha1));
		write_header(sha1, TYPEFLAG_AUTO, basedir, prefix, path,
		             mode, eltbuf, eltsize);
		if (!strcmp(elttype, "tree")) {
			this_prefix.name = path;
			traverse_tree(eltbuf, eltsize, &this_prefix);
		} else if (!strcmp(elttype, "blob") && !S_ISLNK(mode)) {
			write_blocked(eltbuf, eltsize);
		}
		free(eltbuf);
	}
}

/* get commit time from committer line of commit object */
static time_t commit_time(void * buffer, unsigned long size)
{
	time_t result = 0;
	char *p = buffer;

	while (size > 0) {
		char *endp = memchr(p, '\n', size);
		if (!endp || endp == p)
			break;
		*endp = '\0';
		if (endp - p > 10 && !memcmp(p, "committer ", 10)) {
			char *nump = strrchr(p, '>');
			if (!nump)
				break;
			nump++;
			result = strtoul(nump, &endp, 10);
			if (*endp != ' ')
				result = 0;
			break;
		}
		size -= endp - p - 1;
		p = endp + 1;
	}
	return result;
}

int main(int argc, char **argv)
{
	unsigned char sha1[20];
	unsigned char commit_sha1[20];
	void *buffer;
	unsigned long size;

	switch (argc) {
	case 3:
		basedir = argv[2];
		/* FALLTHROUGH */
	case 2:
		if (get_sha1(argv[1], sha1) < 0)
			usage(tar_tree_usage);
		break;
	default:
		usage(tar_tree_usage);
	}

	buffer = read_object_with_reference(sha1, "commit", &size, commit_sha1);
	if (buffer) {
		write_global_extended_header(commit_sha1);
		archive_time = commit_time(buffer, size);
		free(buffer);
	}
	buffer = read_object_with_reference(sha1, "tree", &size, NULL);
	if (!buffer)
		die("not a reference to a tag, commit or tree object: %s",
		    sha1_to_hex(sha1));
	if (!archive_time)
		archive_time = time(NULL);
	if (basedir)
		write_header((unsigned char *)"0", TYPEFLAG_DIR, NULL, NULL,
			basedir, 040755, NULL, 0);
	traverse_tree(buffer, size, NULL);
	free(buffer);
	write_trailer();
	return 0;
}
