#define USE_THE_REPOSITORY_VARIABLE

#include "git-compat-util.h"
#include "dir.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"
#include "tempfile.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);
	struct tempfile *f = NULL;
	int ret = -1;
	struct update_info_ctx uic = {
		.cur_fp = NULL,
		.old_fp = NULL,
		.cur_sb = STRBUF_INIT,
		.old_sb = STRBUF_INIT
	};

	safe_create_leading_directories(path);
	f = mks_tempfile_m(tmp, 0666);
	if (!f)
		goto out;
	uic.cur_fp = fdopen_tempfile(f, "w");
	if (!uic.cur_fp)
		goto out;

	/* 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 (uic_is_stale(&uic)) {
		if (adjust_shared_perm(get_tempfile_path(f)) < 0)
			goto out;
		if (rename_tempfile(&f, path) < 0)
			goto out;
	} else {
		delete_tempfile(&f);
	}
	ret = 0;

out:
	if (ret) {
		error_errno("unable to update %s", path);
		if (f)
			delete_tempfile(&f);
	}
	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 char *referent UNUSED, 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 refs_for_each_ref(get_main_ref_store(the_repository),
				 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",
				   repo_get_object_directory(the_repository));
	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;
}
