#include "cache.h"
#include "skipping.h"
#include "../commit.h"
#include "../fetch-negotiator.h"
#include "../prio-queue.h"
#include "../refs.h"
#include "../tag.h"

/* Remember to update object flag allocation in object.h */
/*
 * Both us and the server know that both parties have this object.
 */
#define COMMON		(1U << 2)
/*
 * The server has told us that it has this object. We still need to tell the
 * server that we have this object (or one of its descendants), but since we are
 * going to do that, we do not need to tell the server about its ancestors.
 */
#define ADVERTISED	(1U << 3)
/*
 * This commit has entered the priority queue.
 */
#define SEEN		(1U << 4)
/*
 * This commit has left the priority queue.
 */
#define POPPED		(1U << 5)

static int marked;

/*
 * An entry in the priority queue.
 */
struct entry {
	struct commit *commit;

	/*
	 * Used only if commit is not COMMON.
	 */
	uint16_t original_ttl;
	uint16_t ttl;
};

struct data {
	struct prio_queue rev_list;

	/*
	 * The number of non-COMMON commits in rev_list.
	 */
	int non_common_revs;
};

static int compare(const void *a_, const void *b_, void *unused)
{
	const struct entry *a = a_;
	const struct entry *b = b_;
	return compare_commits_by_commit_date(a->commit, b->commit, NULL);
}

static struct entry *rev_list_push(struct data *data, struct commit *commit, int mark)
{
	struct entry *entry;
	commit->object.flags |= mark | SEEN;

	CALLOC_ARRAY(entry, 1);
	entry->commit = commit;
	prio_queue_put(&data->rev_list, entry);

	if (!(mark & COMMON))
		data->non_common_revs++;
	return entry;
}

static int clear_marks(const char *refname, const struct object_id *oid,
		       int flag, void *cb_data)
{
	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 | ADVERTISED | SEEN | POPPED);
	return 0;
}

/*
 * Mark this SEEN commit and all its SEEN ancestors as COMMON.
 */
static void mark_common(struct data *data, struct commit *c)
{
	struct commit_list *p;

	if (c->object.flags & COMMON)
		return;
	c->object.flags |= COMMON;
	if (!(c->object.flags & POPPED))
		data->non_common_revs--;

	if (!c->object.parsed)
		return;
	for (p = c->parents; p; p = p->next) {
		if (p->item->object.flags & SEEN)
			mark_common(data, p->item);
	}
}

/*
 * Ensure that the priority queue has an entry for to_push, and ensure that the
 * entry has the correct flags and ttl.
 *
 * This function returns 1 if an entry was found or created, and 0 otherwise
 * (because the entry for this commit had already been popped).
 */
static int push_parent(struct data *data, struct entry *entry,
		       struct commit *to_push)
{
	struct entry *parent_entry;

	if (to_push->object.flags & SEEN) {
		int i;
		if (to_push->object.flags & POPPED)
			/*
			 * The entry for this commit has already been popped,
			 * due to clock skew. Pretend that this parent does not
			 * exist.
			 */
			return 0;
		/*
		 * Find the existing entry and use it.
		 */
		for (i = 0; i < data->rev_list.nr; i++) {
			parent_entry = data->rev_list.array[i].data;
			if (parent_entry->commit == to_push)
				goto parent_found;
		}
		BUG("missing parent in priority queue");
parent_found:
		;
	} else {
		parent_entry = rev_list_push(data, to_push, 0);
	}

	if (entry->commit->object.flags & (COMMON | ADVERTISED)) {
		mark_common(data, to_push);
	} else {
		uint16_t new_original_ttl = entry->ttl
			? entry->original_ttl : entry->original_ttl * 3 / 2 + 1;
		uint16_t new_ttl = entry->ttl
			? entry->ttl - 1 : new_original_ttl;
		if (parent_entry->original_ttl < new_original_ttl) {
			parent_entry->original_ttl = new_original_ttl;
			parent_entry->ttl = new_ttl;
		}
	}

	return 1;
}

static const struct object_id *get_rev(struct data *data)
{
	struct commit *to_send = NULL;

	while (to_send == NULL) {
		struct entry *entry;
		struct commit *commit;
		struct commit_list *p;
		int parent_pushed = 0;

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

		entry = prio_queue_get(&data->rev_list);
		commit = entry->commit;
		commit->object.flags |= POPPED;
		if (!(commit->object.flags & COMMON))
			data->non_common_revs--;

		if (!(commit->object.flags & COMMON) && !entry->ttl)
			to_send = commit;

		parse_commit(commit);
		for (p = commit->parents; p; p = p->next)
			parent_pushed |= push_parent(data, entry, p->item);

		if (!(commit->object.flags & COMMON) && !parent_pushed)
			/*
			 * This commit has no parents, or all of its parents
			 * have already been popped (due to clock skew), so send
			 * it anyway.
			 */
			to_send = commit;

		free(entry);
	}

	return &to_send->object.oid;
}

static void known_common(struct fetch_negotiator *n, struct commit *c)
{
	if (c->object.flags & SEEN)
		return;
	rev_list_push(n->data, c, ADVERTISED);
}

static void add_tip(struct fetch_negotiator *n, struct commit *c)
{
	n->known_common = NULL;
	if (c->object.flags & SEEN)
		return;
	rev_list_push(n->data, c, 0);
}

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);
	if (!(c->object.flags & SEEN))
		die("received ack for commit %s not sent as 'have'\n",
		    oid_to_hex(&c->object.oid));
	mark_common(n->data, c);
	return known_to_be_common;
}

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

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

	if (marked)
		for_each_ref(clear_marks, NULL);
	marked = 1;
}
