#include "git-compat-util.h"
#include "dir.h"
#include "environment.h"
#include "hex.h"
#include "repository.h"
#include "refs.h"
#include "object.h"
#include "commit.h"
#include "tag.h"
#include "packfile.h"
#include "path.h"
#include "object-file.h"
#include "object-store-ll.h"
#include "server-info.h"
#include "strbuf.h"

struct update_info_ctx {
	FILE *cur_fp;
	FILE *old_fp; /* becomes NULL if it differs from cur_fp */
	struct strbuf cur_sb;
	struct strbuf old_sb;
};

static void uic_mark_stale(struct update_info_ctx *uic)
{
	fclose(uic->old_fp);
	uic->old_fp = NULL;
}

static int uic_is_stale(const struct update_info_ctx *uic)
{
	return uic->old_fp == NULL;
}

__attribute__((format (printf, 2, 3)))
static int uic_printf(struct update_info_ctx *uic, const char *fmt, ...)
{
	va_list ap;
	int ret = -1;

	va_start(ap, fmt);

	if (uic_is_stale(uic)) {
		ret = vfprintf(uic->cur_fp, fmt, ap);
	} else {
		ssize_t r;
		struct strbuf *cur = &uic->cur_sb;
		struct strbuf *old = &uic->old_sb;

		strbuf_reset(cur);
		strbuf_vinsertf(cur, 0, fmt, ap);

		strbuf_reset(old);
		strbuf_grow(old, cur->len);
		r = fread(old->buf, 1, cur->len, uic->old_fp);
		if (r != cur->len || memcmp(old->buf, cur->buf, r))
			uic_mark_stale(uic);

		if (fwrite(cur->buf, 1, cur->len, uic->cur_fp) == cur->len)
			ret = 0;
	}

	va_end(ap);

	return ret;
}

/*
 * Create the file "path" by writing to a temporary file and renaming
 * it into place. The contents of the file come from "generate", which
 * should return non-zero if it encounters an error.
 */
static int update_info_file(char *path,
			int (*generate)(struct update_info_ctx *),
			int force)
{
	char *tmp = mkpathdup("%s_XXXXXX", path);
	int ret = -1;
	int fd = -1;
	FILE *to_close;
	struct update_info_ctx uic = {
		.cur_fp = NULL,
		.old_fp = NULL,
		.cur_sb = STRBUF_INIT,
		.old_sb = STRBUF_INIT
	};

	safe_create_leading_directories(path);
	fd = git_mkstemp_mode(tmp, 0666);
	if (fd < 0)
		goto out;
	to_close = uic.cur_fp = fdopen(fd, "w");
	if (!uic.cur_fp)
		goto out;
	fd = -1;

	/* no problem on ENOENT and old_fp == NULL, it's stale, now */
	if (!force)
		uic.old_fp = fopen_or_warn(path, "r");

	/*
	 * uic_printf will compare incremental comparison against old_fp
	 * and mark uic as stale if needed
	 */
	ret = generate(&uic);
	if (ret)
		goto out;

	/* new file may be shorter than the old one, check here */
	if (!uic_is_stale(&uic)) {
		struct stat st;
		long new_len = ftell(uic.cur_fp);
		int old_fd = fileno(uic.old_fp);

		if (new_len < 0) {
			ret = -1;
			goto out;
		}
		if (fstat(old_fd, &st) || (st.st_size != (size_t)new_len))
			uic_mark_stale(&uic);
	}

	uic.cur_fp = NULL;
	if (fclose(to_close))
		goto out;

	if (uic_is_stale(&uic)) {
		if (adjust_shared_perm(tmp) < 0)
			goto out;
		if (rename(tmp, path) < 0)
			goto out;
	} else {
		unlink(tmp);
	}
	ret = 0;

out:
	if (ret) {
		error_errno("unable to update %s", path);
		if (uic.cur_fp)
			fclose(uic.cur_fp);
		else if (fd >= 0)
			close(fd);
		unlink(tmp);
	}
	free(tmp);
	if (uic.old_fp)
		fclose(uic.old_fp);
	strbuf_release(&uic.old_sb);
	strbuf_release(&uic.cur_sb);
	return ret;
}

static int add_info_ref(const char *path, const struct object_id *oid,
			int flag UNUSED,
			void *cb_data)
{
	struct update_info_ctx *uic = cb_data;
	struct object *o = parse_object(the_repository, oid);
	if (!o)
		return -1;

	if (uic_printf(uic, "%s	%s\n", oid_to_hex(oid), path) < 0)
		return -1;

	if (o->type == OBJ_TAG) {
		o = deref_tag(the_repository, o, path, 0);
		if (o)
			if (uic_printf(uic, "%s	%s^{}\n",
				oid_to_hex(&o->oid), path) < 0)
				return -1;
	}
	return 0;
}

static int generate_info_refs(struct update_info_ctx *uic)
{
	return for_each_ref(add_info_ref, uic);
}

static int update_info_refs(int force)
{
	char *path = git_pathdup("info/refs");
	int ret = update_info_file(path, generate_info_refs, force);
	free(path);
	return ret;
}

/* packs */
static struct pack_info {
	struct packed_git *p;
	int old_num;
	int new_num;
} **info;
static int num_pack;

static struct pack_info *find_pack_by_name(const char *name)
{
	int i;
	for (i = 0; i < num_pack; i++) {
		struct packed_git *p = info[i]->p;
		if (!strcmp(pack_basename(p), name))
			return info[i];
	}
	return NULL;
}

/* Returns non-zero when we detect that the info in the
 * old file is useless.
 */
static int parse_pack_def(const char *packname, int old_cnt)
{
	struct pack_info *i = find_pack_by_name(packname);
	if (i) {
		i->old_num = old_cnt;
		return 0;
	}
	else {
		/* The file describes a pack that is no longer here */
		return 1;
	}
}

/* Returns non-zero when we detect that the info in the
 * old file is useless.
 */
static int read_pack_info_file(const char *infofile)
{
	FILE *fp;
	struct strbuf line = STRBUF_INIT;
	int old_cnt = 0;
	int stale = 1;

	fp = fopen_or_warn(infofile, "r");
	if (!fp)
		return 1; /* nonexistent is not an error. */

	while (strbuf_getline(&line, fp) != EOF) {
		const char *arg;

		if (!line.len)
			continue;

		if (skip_prefix(line.buf, "P ", &arg)) {
			/* P name */
			if (parse_pack_def(arg, old_cnt++))
				goto out_stale;
		} else if (line.buf[0] == 'D') {
			/* we used to emit D but that was misguided. */
			goto out_stale;
		} else if (line.buf[0] == 'T') {
			/* we used to emit T but nobody uses it. */
			goto out_stale;
		} else {
			error("unrecognized: %s", line.buf);
		}
	}
	stale = 0;

 out_stale:
	strbuf_release(&line);
	fclose(fp);
	return stale;
}

static int compare_info(const void *a_, const void *b_)
{
	struct pack_info *const *a = a_;
	struct pack_info *const *b = b_;

	if (0 <= (*a)->old_num && 0 <= (*b)->old_num)
		/* Keep the order in the original */
		return (*a)->old_num - (*b)->old_num;
	else if (0 <= (*a)->old_num)
		/* Only A existed in the original so B is obviously newer */
		return -1;
	else if (0 <= (*b)->old_num)
		/* The other way around. */
		return 1;

	/* then it does not matter but at least keep the comparison stable */
	if ((*a)->p == (*b)->p)
		return 0;
	else if ((*a)->p < (*b)->p)
		return -1;
	else
		return 1;
}

static void init_pack_info(const char *infofile, int force)
{
	struct packed_git *p;
	int stale;
	int i;
	size_t alloc = 0;

	for (p = get_all_packs(the_repository); p; p = p->next) {
		/* we ignore things on alternate path since they are
		 * not available to the pullers in general.
		 */
		if (!p->pack_local || !file_exists(p->pack_name))
			continue;

		i = num_pack++;
		ALLOC_GROW(info, num_pack, alloc);
		CALLOC_ARRAY(info[i], 1);
		info[i]->p = p;
		info[i]->old_num = -1;
	}

	if (infofile && !force)
		stale = read_pack_info_file(infofile);
	else
		stale = 1;

	for (i = 0; i < num_pack; i++)
		if (stale)
			info[i]->old_num = -1;

	/* renumber them */
	QSORT(info, num_pack, compare_info);
	for (i = 0; i < num_pack; i++)
		info[i]->new_num = i;
}

static void free_pack_info(void)
{
	int i;
	for (i = 0; i < num_pack; i++)
		free(info[i]);
	free(info);
}

static int write_pack_info_file(struct update_info_ctx *uic)
{
	int i;
	for (i = 0; i < num_pack; i++) {
		if (uic_printf(uic, "P %s\n", pack_basename(info[i]->p)) < 0)
			return -1;
	}
	if (uic_printf(uic, "\n") < 0)
		return -1;
	return 0;
}

static int update_info_packs(int force)
{
	char *infofile = mkpathdup("%s/info/packs", get_object_directory());
	int ret;

	init_pack_info(infofile, force);
	ret = update_info_file(infofile, write_pack_info_file, force);
	free_pack_info();
	free(infofile);
	return ret;
}

/* public */
int update_server_info(int force)
{
	/* We would add more dumb-server support files later,
	 * including index of available pack files and their
	 * intended audiences.
	 */
	int errs = 0;

	errs = errs | update_info_refs(force);
	errs = errs | update_info_packs(force);

	/* remove leftover rev-cache file if there is any */
	unlink_or_warn(git_path("info/rev-cache"));

	return errs;
}
