#define USE_THE_REPOSITORY_VARIABLE

#include "git-compat-util.h"
#include "default.h"
#include "../commit.h"
#include "../fetch-negotiator.h"
#include "../prio-queue.h"
#include "../refs.h"
#include "../repository.h"
#include "../tag.h"

/* Remember to update object flag allocation in object.h */
#define COMMON		(1U << 2)
#define COMMON_REF	(1U << 3)
#define SEEN		(1U << 4)
#define POPPED		(1U << 5)

static int marked;

struct negotiation_state {
	struct prio_queue rev_list;
	int non_common_revs;
};

static void rev_list_push(struct negotiation_state *ns,
			  struct commit *commit, int mark)
{
	if (!(commit->object.flags & mark)) {
		commit->object.flags |= mark;

		if (repo_parse_commit(the_repository, commit))
			return;

		prio_queue_put(&ns->rev_list, commit);

		if (!(commit->object.flags & COMMON))
			ns->non_common_revs++;
	}
}

static int clear_marks(const char *refname, const struct object_id *oid,
		       int flag UNUSED,
		       void *cb_data UNUSED)
{
	struct object *o = deref_tag(the_repository, parse_object(the_repository, oid), refname, 0);

	if (o && o->type == OBJ_COMMIT)
		clear_commit_marks((struct commit *)o,
				   COMMON | COMMON_REF | SEEN | POPPED);
	return 0;
}

/*
 * This function marks a rev and its ancestors as common.
 * In some cases, it is desirable to mark only the ancestors (for example
 * when only the server does not yet know that they are common).
 */
static void mark_common(struct negotiation_state *ns, struct commit *commit,
		int ancestors_only, int dont_parse)
{
	struct prio_queue queue = { NULL };

	if (!commit || (commit->object.flags & COMMON))
		return;

	prio_queue_put(&queue, commit);
	if (!ancestors_only) {
		commit->object.flags |= COMMON;

		if ((commit->object.flags & SEEN) && !(commit->object.flags & POPPED))
			ns->non_common_revs--;
	}
	while ((commit = prio_queue_get(&queue))) {
		struct object *o = (struct object *)commit;

		if (!(o->flags & SEEN))
			rev_list_push(ns, commit, SEEN);
		else {
			struct commit_list *parents;

			if (!o->parsed && !dont_parse)
				if (repo_parse_commit(the_repository, commit))
					continue;

			for (parents = commit->parents;
					parents;
					parents = parents->next) {
				struct commit *p = parents->item;

				if (p->object.flags & COMMON)
					continue;

				p->object.flags |= COMMON;

				if ((p->object.flags & SEEN) && !(p->object.flags & POPPED))
					ns->non_common_revs--;

				prio_queue_put(&queue, parents->item);
			}
		}
	}

	clear_prio_queue(&queue);
}

/*
 * Get the next rev to send, ignoring the common.
 */
static const struct object_id *get_rev(struct negotiation_state *ns)
{
	struct commit *commit = NULL;

	while (commit == NULL) {
		unsigned int mark;
		struct commit_list *parents;

		if (ns->rev_list.nr == 0 || ns->non_common_revs == 0)
			return NULL;

		commit = prio_queue_get(&ns->rev_list);
		repo_parse_commit(the_repository, commit);
		parents = commit->parents;

		commit->object.flags |= POPPED;
		if (!(commit->object.flags & COMMON))
			ns->non_common_revs--;

		if (commit->object.flags & COMMON) {
			/* do not send "have", and ignore ancestors */
			commit = NULL;
			mark = COMMON | SEEN;
		} else if (commit->object.flags & COMMON_REF)
			/* send "have", and ignore ancestors */
			mark = COMMON | SEEN;
		else
			/* send "have", also for its ancestors */
			mark = SEEN;

		while (parents) {
			if (!(parents->item->object.flags & SEEN))
				rev_list_push(ns, parents->item, mark);
			if (mark & COMMON)
				mark_common(ns, parents->item, 1, 0);
			parents = parents->next;
		}
	}

	return &commit->object.oid;
}

static void known_common(struct fetch_negotiator *n, struct commit *c)
{
	if (!(c->object.flags & SEEN)) {
		rev_list_push(n->data, c, COMMON_REF | SEEN);
		mark_common(n->data, c, 1, 1);
	}
}

static void add_tip(struct fetch_negotiator *n, struct commit *c)
{
	n->known_common = NULL;
	rev_list_push(n->data, c, SEEN);
}

static const struct object_id *next(struct fetch_negotiator *n)
{
	n->known_common = NULL;
	n->add_tip = NULL;
	return get_rev(n->data);
}

static int ack(struct fetch_negotiator *n, struct commit *c)
{
	int known_to_be_common = !!(c->object.flags & COMMON);
	mark_common(n->data, c, 0, 1);
	return known_to_be_common;
}

static void release(struct fetch_negotiator *n)
{
	clear_prio_queue(&((struct negotiation_state *)n->data)->rev_list);
	FREE_AND_NULL(n->data);
}

void default_negotiator_init(struct fetch_negotiator *negotiator)
{
	struct negotiation_state *ns;
	negotiator->known_common = known_common;
	negotiator->add_tip = add_tip;
	negotiator->next = next;
	negotiator->ack = ack;
	negotiator->release = release;
	negotiator->data = CALLOC_ARRAY(ns, 1);
	ns->rev_list.compare = compare_commits_by_commit_date;

	if (marked)
		refs_for_each_ref(get_main_ref_store(the_repository),
				  clear_marks, NULL);
	marked = 1;
}
