#include "git-compat-util.h"
#include "gettext.h"
#include "hex.h"
#include "refs.h"
#include "tag.h"
#include "commit.h"
#include "blob.h"
#include "diff.h"
#include "revision.h"
#include "reachable.h"
#include "cache-tree.h"
#include "progress.h"
#include "list-objects.h"
#include "packfile.h"
#include "worktree.h"
#include "object-store.h"
#include "pack-bitmap.h"
#include "pack-mtimes.h"

struct connectivity_progress {
	struct progress *progress;
	unsigned long count;
};

static void update_progress(struct connectivity_progress *cp)
{
	cp->count++;
	if ((cp->count & 1023) == 0)
		display_progress(cp->progress, cp->count);
}

static int add_one_ref(const char *path, const struct object_id *oid,
		       int flag, void *cb_data)
{
	struct rev_info *revs = (struct rev_info *)cb_data;
	struct object *object;

	if ((flag & REF_ISSYMREF) && (flag & REF_ISBROKEN)) {
		warning("symbolic ref is dangling: %s", path);
		return 0;
	}

	object = parse_object_or_die(oid, path);
	add_pending_object(revs, object, "");

	return 0;
}

/*
 * The traversal will have already marked us as SEEN, so we
 * only need to handle any progress reporting here.
 */
static void mark_object(struct object *obj UNUSED,
			const char *name UNUSED,
			void *data)
{
	update_progress(data);
}

static void mark_commit(struct commit *c, void *data)
{
	mark_object(&c->object, NULL, data);
}

struct recent_data {
	struct rev_info *revs;
	timestamp_t timestamp;
	report_recent_object_fn *cb;
	int ignore_in_core_kept_packs;
};

static void add_recent_object(const struct object_id *oid,
			      struct packed_git *pack,
			      off_t offset,
			      timestamp_t mtime,
			      struct recent_data *data)
{
	struct object *obj;
	enum object_type type;

	if (mtime <= data->timestamp)
		return;

	/*
	 * We do not want to call parse_object here, because
	 * inflating blobs and trees could be very expensive.
	 * However, we do need to know the correct type for
	 * later processing, and the revision machinery expects
	 * commits and tags to have been parsed.
	 */
	type = oid_object_info(the_repository, oid, NULL);
	if (type < 0)
		die("unable to get object info for %s", oid_to_hex(oid));

	switch (type) {
	case OBJ_TAG:
	case OBJ_COMMIT:
		obj = parse_object_or_die(oid, NULL);
		break;
	case OBJ_TREE:
		obj = (struct object *)lookup_tree(the_repository, oid);
		break;
	case OBJ_BLOB:
		obj = (struct object *)lookup_blob(the_repository, oid);
		break;
	default:
		die("unknown object type for %s: %s",
		    oid_to_hex(oid), type_name(type));
	}

	if (!obj)
		die("unable to lookup %s", oid_to_hex(oid));

	add_pending_object(data->revs, obj, "");
	if (data->cb)
		data->cb(obj, pack, offset, mtime);
}

static int want_recent_object(struct recent_data *data,
			      const struct object_id *oid)
{
	if (data->ignore_in_core_kept_packs &&
	    has_object_kept_pack(oid, IN_CORE_KEEP_PACKS))
		return 0;
	return 1;
}

static int add_recent_loose(const struct object_id *oid,
			    const char *path, void *data)
{
	struct stat st;
	struct object *obj;

	if (!want_recent_object(data, oid))
		return 0;

	obj = lookup_object(the_repository, oid);

	if (obj && obj->flags & SEEN)
		return 0;

	if (stat(path, &st) < 0) {
		/*
		 * It's OK if an object went away during our iteration; this
		 * could be due to a simultaneous repack. But anything else
		 * we should abort, since we might then fail to mark objects
		 * which should not be pruned.
		 */
		if (errno == ENOENT)
			return 0;
		return error_errno("unable to stat %s", oid_to_hex(oid));
	}

	add_recent_object(oid, NULL, 0, st.st_mtime, data);
	return 0;
}

static int add_recent_packed(const struct object_id *oid,
			     struct packed_git *p,
			     uint32_t pos,
			     void *data)
{
	struct object *obj;
	timestamp_t mtime = p->mtime;

	if (!want_recent_object(data, oid))
		return 0;

	obj = lookup_object(the_repository, oid);

	if (obj && obj->flags & SEEN)
		return 0;
	if (p->is_cruft) {
		if (load_pack_mtimes(p) < 0)
			die(_("could not load cruft pack .mtimes"));
		mtime = nth_packed_mtime(p, pos);
	}
	add_recent_object(oid, p, nth_packed_object_offset(p, pos), mtime, data);
	return 0;
}

int add_unseen_recent_objects_to_traversal(struct rev_info *revs,
					   timestamp_t timestamp,
					   report_recent_object_fn *cb,
					   int ignore_in_core_kept_packs)
{
	struct recent_data data;
	enum for_each_object_flags flags;
	int r;

	data.revs = revs;
	data.timestamp = timestamp;
	data.cb = cb;
	data.ignore_in_core_kept_packs = ignore_in_core_kept_packs;

	r = for_each_loose_object(add_recent_loose, &data,
				  FOR_EACH_OBJECT_LOCAL_ONLY);
	if (r)
		return r;

	flags = FOR_EACH_OBJECT_LOCAL_ONLY | FOR_EACH_OBJECT_PACK_ORDER;
	if (ignore_in_core_kept_packs)
		flags |= FOR_EACH_OBJECT_SKIP_IN_CORE_KEPT_PACKS;

	return for_each_packed_object(add_recent_packed, &data, flags);
}

static int mark_object_seen(const struct object_id *oid,
			     enum object_type type,
			     int exclude UNUSED,
			     uint32_t name_hash UNUSED,
			     struct packed_git *found_pack UNUSED,
			     off_t found_offset UNUSED)
{
	struct object *obj = lookup_object_by_type(the_repository, oid, type);
	if (!obj)
		die("unable to create object '%s'", oid_to_hex(oid));

	obj->flags |= SEEN;
	return 0;
}

void mark_reachable_objects(struct rev_info *revs, int mark_reflog,
			    timestamp_t mark_recent, struct progress *progress)
{
	struct connectivity_progress cp;
	struct bitmap_index *bitmap_git;

	/*
	 * Set up revision parsing, and mark us as being interested
	 * in all object types, not just commits.
	 */
	revs->tag_objects = 1;
	revs->blob_objects = 1;
	revs->tree_objects = 1;

	/* Add all refs from the index file */
	add_index_objects_to_pending(revs, 0);

	/* Add all external refs */
	for_each_ref(add_one_ref, revs);

	/* detached HEAD is not included in the list above */
	head_ref(add_one_ref, revs);
	other_head_refs(add_one_ref, revs);

	/* Add all reflog info */
	if (mark_reflog)
		add_reflogs_to_pending(revs, 0);

	cp.progress = progress;
	cp.count = 0;

	bitmap_git = prepare_bitmap_walk(revs, 0);
	if (bitmap_git) {
		traverse_bitmap_commit_list(bitmap_git, revs, mark_object_seen);
		free_bitmap_index(bitmap_git);
	} else {
		if (prepare_revision_walk(revs))
			die("revision walk setup failed");
		traverse_commit_list(revs, mark_commit, mark_object, &cp);
	}

	if (mark_recent) {
		revs->ignore_missing_links = 1;
		if (add_unseen_recent_objects_to_traversal(revs, mark_recent,
							   NULL, 0))
			die("unable to mark recent objects");
		if (prepare_revision_walk(revs))
			die("revision walk setup failed");
		traverse_commit_list(revs, mark_commit, mark_object, &cp);
	}

	display_progress(cp.progress, cp.count);
}
