/*
 * Copyright (C) 2005 Junio C Hamano
 */

#define USE_THE_REPOSITORY_VARIABLE
#define DISABLE_SIGN_COMPARE_WARNINGS

#include "git-compat-util.h"
#include "commit.h"
#include "diff.h"
#include "diffcore.h"
#include "gettext.h"
#include "hash.h"
#include "hex.h"
#include "object-name.h"
#include "read-cache.h"
#include "revision.h"
#include "cache-tree.h"
#include "unpack-trees.h"
#include "refs.h"
#include "repository.h"
#include "submodule.h"
#include "symlinks.h"
#include "trace.h"
#include "dir.h"
#include "fsmonitor.h"
#include "commit-reach.h"

/*
 * diff-files
 */

/*
 * Has the work tree entity been removed?
 *
 * Return 1 if it was removed from the work tree, 0 if an entity to be
 * compared with the cache entry ce still exists (the latter includes
 * the case where a directory that is not a submodule repository
 * exists for ce that is a submodule -- it is a submodule that is not
 * checked out).  Return negative for an error.
 */
static int check_removed(const struct cache_entry *ce, struct stat *st)
{
	int stat_err;

	if (!(ce->ce_flags & CE_FSMONITOR_VALID))
		stat_err = lstat(ce->name, st);
	else
		stat_err = fake_lstat(ce, st);
	if (stat_err < 0) {
		if (!is_missing_file_error(errno))
			return -1;
		return 1;
	}

	if (has_symlink_leading_path(ce->name, ce_namelen(ce)))
		return 1;
	if (S_ISDIR(st->st_mode)) {
		struct object_id sub;

		/*
		 * If ce is already a gitlink, we can have a plain
		 * directory (i.e. the submodule is not checked out),
		 * or a checked out submodule.  Either case this is not
		 * a case where something was removed from the work tree,
		 * so we will return 0.
		 *
		 * Otherwise, if the directory is not a submodule
		 * repository, that means ce which was a blob turned into
		 * a directory --- the blob was removed!
		 */
		if (!S_ISGITLINK(ce->ce_mode) &&
		    repo_resolve_gitlink_ref(the_repository, ce->name,
					     "HEAD", &sub))
			return 1;
	}
	return 0;
}

/*
 * Has a file changed or has a submodule new commits or a dirty work tree?
 *
 * Return 1 when changes are detected, 0 otherwise. If the DIRTY_SUBMODULES
 * option is set, the caller does not only want to know if a submodule is
 * modified at all but wants to know all the conditions that are met (new
 * commits, untracked content and/or modified content).
 */
static int match_stat_with_submodule(struct diff_options *diffopt,
				     const struct cache_entry *ce,
				     struct stat *st, unsigned ce_option,
				     unsigned *dirty_submodule)
{
	int changed = ie_match_stat(diffopt->repo->index, ce, st, ce_option);
	if (S_ISGITLINK(ce->ce_mode)) {
		struct diff_flags orig_flags = diffopt->flags;
		if (!diffopt->flags.override_submodule_config)
			set_diffopt_flags_from_submodule_config(diffopt, ce->name);
		if (diffopt->flags.ignore_submodules)
			changed = 0;
		else if (!diffopt->flags.ignore_dirty_submodules &&
			 (!changed || diffopt->flags.dirty_submodules))
			*dirty_submodule = is_submodule_modified(ce->name,
								 diffopt->flags.ignore_untracked_in_submodules);
		diffopt->flags = orig_flags;
	}
	return changed;
}

void run_diff_files(struct rev_info *revs, unsigned int option)
{
	int entries, i;
	int diff_unmerged_stage = revs->max_count;
	unsigned ce_option = ((option & DIFF_RACY_IS_MODIFIED)
			      ? CE_MATCH_RACY_IS_DIRTY : 0);
	uint64_t start = getnanotime();
	struct index_state *istate = revs->diffopt.repo->index;

	if (revs->diffopt.max_depth_valid)
		die(_("max-depth is not supported for worktree diffs"));

	diff_set_mnemonic_prefix(&revs->diffopt, "i/", "w/");

	refresh_fsmonitor(istate);

	if (diff_unmerged_stage < 0)
		diff_unmerged_stage = 2;
	entries = istate->cache_nr;
	for (i = 0; i < entries; i++) {
		unsigned int oldmode, newmode;
		struct cache_entry *ce = istate->cache[i];
		int changed;
		unsigned dirty_submodule = 0;
		const struct object_id *old_oid, *new_oid;

		if (diff_can_quit_early(&revs->diffopt))
			break;

		/*
		 * NEEDSWORK:
		 * Here we filter with pathspec but the result is further
		 * filtered out when --relative is in effect.  To end-users,
		 * a pathspec element that matched only to paths outside the
		 * current directory is like not matching anything at all;
		 * the handling of ps_matched[] here may become problematic
		 * if/when we add the "--error-unmatch" option to "git diff".
		 */
		if (!ce_path_match(istate, ce, &revs->prune_data, revs->ps_matched))
			continue;

		if (revs->diffopt.prefix &&
		    strncmp(ce->name, revs->diffopt.prefix, revs->diffopt.prefix_length))
			continue;

		if (ce_stage(ce)) {
			struct combine_diff_path *dpath;
			struct diff_filepair *pair;
			unsigned int wt_mode = 0;
			int num_compare_stages = 0;
			struct stat st;

			changed = check_removed(ce, &st);
			if (!changed)
				wt_mode = ce_mode_from_stat(ce, st.st_mode);
			else {
				if (changed < 0) {
					perror(ce->name);
					continue;
				}
				wt_mode = 0;
			}

			/*
			 * Allocate space for two parents, which will come from
			 * index stages #2 and #3, if present. Below we'll fill
			 * these from (stage - 2).
			 */
			dpath = combine_diff_path_new(ce->name, ce_namelen(ce),
						      wt_mode, null_oid(the_hash_algo), 2);

			while (i < entries) {
				struct cache_entry *nce = istate->cache[i];
				int stage;

				if (strcmp(ce->name, nce->name))
					break;

				/* Stage #2 (ours) is the first parent,
				 * stage #3 (theirs) is the second.
				 */
				stage = ce_stage(nce);
				if (2 <= stage) {
					int mode = nce->ce_mode;
					num_compare_stages++;
					oidcpy(&dpath->parent[stage - 2].oid,
					       &nce->oid);
					dpath->parent[stage-2].mode = ce_mode_from_stat(nce, mode);
					dpath->parent[stage-2].status =
						DIFF_STATUS_MODIFIED;
				}

				/* diff against the proper unmerged stage */
				if (stage == diff_unmerged_stage)
					ce = nce;
				i++;
			}
			/*
			 * Compensate for loop update
			 */
			i--;

			if (revs->combine_merges && num_compare_stages == 2) {
				show_combined_diff(dpath, 2, revs);
				free(dpath);
				continue;
			}
			FREE_AND_NULL(dpath);

			/*
			 * Show the diff for the 'ce' if we found the one
			 * from the desired stage.
			 */
			pair = diff_unmerge(&revs->diffopt, ce->name);
			if (wt_mode)
				pair->two->mode = wt_mode;
			if (ce_stage(ce) != diff_unmerged_stage)
				continue;
		}

		if (ce_uptodate(ce) || ce_skip_worktree(ce)) {
			if (revs->diffopt.flags.find_copies_harder)
				diff_same(&revs->diffopt, ce->ce_mode,
					  &ce->oid, ce->name);
			continue;
		}

		/*
		 * When CE_VALID is set (via "update-index --assume-unchanged"
		 * or via adding paths while core.ignorestat is set to true),
		 * the user has promised that the working tree file for that
		 * path will not be modified.  When CE_FSMONITOR_VALID is true,
		 * the fsmonitor knows that the path hasn't been modified since
		 * we refreshed the cached stat information.  In either case,
		 * we do not have to stat to see if the path has been removed
		 * or modified.
		 */
		if (ce->ce_flags & (CE_VALID | CE_FSMONITOR_VALID)) {
			changed = 0;
			newmode = ce->ce_mode;
		} else {
			struct stat st;

			changed = check_removed(ce, &st);
			if (changed) {
				if (changed < 0) {
					perror(ce->name);
					continue;
				}
				diff_addremove(&revs->diffopt, '-', ce->ce_mode,
					       &ce->oid,
					       !is_null_oid(&ce->oid),
					       ce->name, 0);
				continue;
			} else if (revs->diffopt.ita_invisible_in_index &&
				   ce_intent_to_add(ce)) {
				newmode = ce_mode_from_stat(ce, st.st_mode);
				diff_addremove(&revs->diffopt, '+', newmode,
					       null_oid(the_hash_algo), 0, ce->name, 0);
				continue;
			}

			changed = match_stat_with_submodule(&revs->diffopt, ce, &st,
							    ce_option, &dirty_submodule);
			newmode = ce_mode_from_stat(ce, st.st_mode);
		}

		if (!changed && !dirty_submodule) {
			ce_mark_uptodate(ce);
			mark_fsmonitor_valid(istate, ce);
			if (revs->diffopt.flags.find_copies_harder)
				diff_same(&revs->diffopt, newmode,
					  &ce->oid, ce->name);
			continue;
		}
		oldmode = ce->ce_mode;
		old_oid = &ce->oid;
		new_oid = changed ? null_oid(the_hash_algo) : &ce->oid;
		diff_change(&revs->diffopt, oldmode, newmode,
			    old_oid, new_oid,
			    !is_null_oid(old_oid),
			    !is_null_oid(new_oid),
			    ce->name, 0, dirty_submodule);

	}
	diffcore_std(&revs->diffopt);
	diff_flush(&revs->diffopt);
	trace_performance_since(start, "diff-files");
}

/*
 * diff-index
 */

/* A file entry went away or appeared */
static void diff_index_show_file(struct rev_info *revs,
				 const char *prefix,
				 const struct cache_entry *ce,
				 const struct object_id *oid, int oid_valid,
				 unsigned int mode,
				 unsigned dirty_submodule)
{
	diff_addremove(&revs->diffopt, prefix[0], mode,
		       oid, oid_valid, ce->name, dirty_submodule);
}

static int get_stat_data(const struct cache_entry *ce,
			 const struct object_id **oidp,
			 unsigned int *modep,
			 int cached, int match_missing,
			 unsigned *dirty_submodule, struct diff_options *diffopt)
{
	const struct object_id *oid = &ce->oid;
	unsigned int mode = ce->ce_mode;

	if (!cached && !ce_uptodate(ce)) {
		int changed;
		struct stat st;
		changed = check_removed(ce, &st);
		if (changed < 0)
			return -1;
		else if (changed) {
			if (match_missing) {
				*oidp = oid;
				*modep = mode;
				return 0;
			}
			return -1;
		}
		changed = match_stat_with_submodule(diffopt, ce, &st,
						    0, dirty_submodule);
		if (changed) {
			mode = ce_mode_from_stat(ce, st.st_mode);
			oid = null_oid(the_hash_algo);
		}
	}

	*oidp = oid;
	*modep = mode;
	return 0;
}

static void show_new_file(struct rev_info *revs,
			  const struct cache_entry *new_file,
			  int cached, int match_missing)
{
	const struct object_id *oid;
	unsigned int mode;
	unsigned dirty_submodule = 0;

	if (new_file && S_ISSPARSEDIR(new_file->ce_mode)) {
		diff_tree_oid(NULL, &new_file->oid, new_file->name, &revs->diffopt);
		return;
	}

	/*
	 * New file in the index: it might actually be different in
	 * the working tree.
	 */
	if (get_stat_data(new_file, &oid, &mode, cached, match_missing,
	    &dirty_submodule, &revs->diffopt) < 0)
		return;

	diff_index_show_file(revs, "+", new_file, oid, !is_null_oid(oid), mode, dirty_submodule);
}

static int show_modified(struct rev_info *revs,
			 const struct cache_entry *old_entry,
			 const struct cache_entry *new_entry,
			 int report_missing,
			 int cached, int match_missing)
{
	unsigned int mode, oldmode;
	const struct object_id *oid;
	unsigned dirty_submodule = 0;

	assert(S_ISSPARSEDIR(old_entry->ce_mode) ==
	       S_ISSPARSEDIR(new_entry->ce_mode));

	/*
	 * If both are sparse directory entries, then expand the
	 * modifications to the file level. If only one was a sparse
	 * directory, then they appear as an add and delete instead of
	 * a modification.
	 */
	if (S_ISSPARSEDIR(new_entry->ce_mode)) {
		diff_tree_oid(&old_entry->oid, &new_entry->oid, new_entry->name, &revs->diffopt);
		return 0;
	}

	if (get_stat_data(new_entry, &oid, &mode, cached, match_missing,
			  &dirty_submodule, &revs->diffopt) < 0) {
		if (report_missing)
			diff_index_show_file(revs, "-", old_entry,
					     &old_entry->oid, 1, old_entry->ce_mode,
					     0);
		return -1;
	}

	if (revs->combine_merges && !cached &&
	    (!oideq(oid, &old_entry->oid) || !oideq(&old_entry->oid, &new_entry->oid))) {
		struct combine_diff_path *p;

		p = combine_diff_path_new(new_entry->name,
					  ce_namelen(new_entry),
					  mode, null_oid(the_hash_algo), 2);
		p->parent[0].status = DIFF_STATUS_MODIFIED;
		p->parent[0].mode = new_entry->ce_mode;
		oidcpy(&p->parent[0].oid, &new_entry->oid);
		p->parent[1].status = DIFF_STATUS_MODIFIED;
		p->parent[1].mode = old_entry->ce_mode;
		oidcpy(&p->parent[1].oid, &old_entry->oid);
		show_combined_diff(p, 2, revs);
		free(p);
		return 0;
	}

	oldmode = old_entry->ce_mode;
	if (mode != oldmode || !oideq(oid, &old_entry->oid) || dirty_submodule)
		diff_change(&revs->diffopt, oldmode, mode,
			    &old_entry->oid, oid, 1, !is_null_oid(oid),
			    old_entry->name, 0, dirty_submodule);
	else if (revs->diffopt.flags.find_copies_harder)
		diff_same(&revs->diffopt, mode, oid, old_entry->name);
	return 0;
}

/*
 * This gets a mix of an existing index and a tree, one pathname entry
 * at a time. The index entry may be a single stage-0 one, but it could
 * also be multiple unmerged entries (in which case idx_pos/idx_nr will
 * give you the position and number of entries in the index).
 */
static void do_oneway_diff(struct unpack_trees_options *o,
			   const struct cache_entry *idx,
			   const struct cache_entry *tree)
{
	struct rev_info *revs = o->unpack_data;
	int match_missing, cached;

	/*
	 * i-t-a entries do not actually exist in the index (if we're
	 * looking at its content)
	 */
	if (o->index_only &&
	    revs->diffopt.ita_invisible_in_index &&
	    idx && ce_intent_to_add(idx)) {
		idx = NULL;
		if (!tree)
			return;	/* nothing to diff.. */
	}

	/* if the entry is not checked out, don't examine work tree */
	cached = o->index_only ||
		(idx && ((idx->ce_flags & CE_VALID) || ce_skip_worktree(idx)));

	match_missing = revs->match_missing;

	if (cached && idx && ce_stage(idx)) {
		struct diff_filepair *pair;
		pair = diff_unmerge(&revs->diffopt, idx->name);
		if (tree)
			fill_filespec(pair->one, &tree->oid, 1,
				      tree->ce_mode);
		return;
	}

	/*
	 * Something added to the tree?
	 */
	if (!tree) {
		show_new_file(revs, idx, cached, match_missing);
		return;
	}

	/*
	 * Something removed from the tree?
	 */
	if (!idx) {
		if (S_ISSPARSEDIR(tree->ce_mode)) {
			diff_tree_oid(&tree->oid, NULL, tree->name, &revs->diffopt);
			return;
		}

		diff_index_show_file(revs, "-", tree, &tree->oid, 1,
				     tree->ce_mode, 0);
		return;
	}

	/* Show difference between old and new */
	show_modified(revs, tree, idx, 1, cached, match_missing);
}

/*
 * The unpack_trees() interface is designed for merging, so
 * the different source entries are designed primarily for
 * the source trees, with the old index being really mainly
 * used for being replaced by the result.
 *
 * For diffing, the index is more important, and we only have a
 * single tree.
 *
 * We're supposed to advance o->pos to skip what we have already processed.
 *
 * This wrapper makes it all more readable, and takes care of all
 * the fairly complex unpack_trees() semantic requirements, including
 * the skipping, the path matching, the type conflict cases etc.
 */
static int oneway_diff(const struct cache_entry * const *src,
		       struct unpack_trees_options *o)
{
	const struct cache_entry *idx = src[0];
	const struct cache_entry *tree = src[1];
	struct rev_info *revs = o->unpack_data;

	/*
	 * Unpack-trees generates a DF/conflict entry if
	 * there was a directory in the index and a tree
	 * in the tree. From a diff standpoint, that's a
	 * delete of the tree and a create of the file.
	 */
	if (tree == o->df_conflict_entry)
		tree = NULL;

	if (ce_path_match(revs->diffopt.repo->index,
			  idx ? idx : tree,
			  &revs->prune_data, NULL)) {
		do_oneway_diff(o, idx, tree);
		if (diff_can_quit_early(&revs->diffopt)) {
			o->exiting_early = 1;
			return -1;
		}
	}

	return 0;
}

static int diff_cache(struct rev_info *revs,
		      const struct object_id *tree_oid,
		      const char *tree_name,
		      int cached)
{
	struct tree *tree;
	struct tree_desc t;
	struct unpack_trees_options opts;

	tree = parse_tree_indirect(tree_oid);
	if (!tree)
		return error("bad tree object %s",
			     tree_name ? tree_name : oid_to_hex(tree_oid));
	memset(&opts, 0, sizeof(opts));
	opts.head_idx = 1;
	opts.index_only = cached;
	opts.diff_index_cached = (cached &&
				  !revs->diffopt.flags.find_copies_harder);
	opts.merge = 1;
	opts.fn = oneway_diff;
	opts.unpack_data = revs;
	opts.src_index = revs->diffopt.repo->index;
	opts.dst_index = NULL;
	opts.pathspec = &revs->diffopt.pathspec;
	opts.pathspec->recursive = 1;
	if (revs->diffopt.max_depth_valid)
		die(_("max-depth is not supported for index diffs"));

	init_tree_desc(&t, &tree->object.oid, tree->buffer, tree->size);
	return unpack_trees(1, &t, &opts);
}

void diff_get_merge_base(const struct rev_info *revs, struct object_id *mb)
{
	int i;
	struct commit *mb_child[2] = {0};
	struct commit_list *merge_bases = NULL;

	for (i = 0; i < revs->pending.nr; i++) {
		struct object *obj = revs->pending.objects[i].item;
		if (obj->flags)
			die(_("--merge-base does not work with ranges"));
	}

	/*
	 * This check must go after the for loop above because A...B
	 * ranges produce three pending commits, resulting in a
	 * misleading error message.
	 */
	if (revs->pending.nr < 1 || revs->pending.nr > 2)
		BUG("unexpected revs->pending.nr: %d", revs->pending.nr);

	for (i = 0; i < revs->pending.nr; i++)
		mb_child[i] = lookup_commit_reference(the_repository, &revs->pending.objects[i].item->oid);
	if (revs->pending.nr == 1) {
		struct object_id oid;

		if (repo_get_oid(the_repository, "HEAD", &oid))
			die(_("unable to get HEAD"));

		mb_child[1] = lookup_commit_reference(the_repository, &oid);
	}

	if (repo_get_merge_bases(the_repository, mb_child[0], mb_child[1], &merge_bases) < 0)
		exit(128);
	if (!merge_bases)
		die(_("no merge base found"));
	if (merge_bases->next)
		die(_("multiple merge bases found"));

	oidcpy(mb, &merge_bases->item->object.oid);

	free_commit_list(merge_bases);
}

void run_diff_index(struct rev_info *revs, unsigned int option)
{
	struct object_array_entry *ent;
	int cached = !!(option & DIFF_INDEX_CACHED);
	int merge_base = !!(option & DIFF_INDEX_MERGE_BASE);
	struct object_id oid;
	const char *name;
	char merge_base_hex[GIT_MAX_HEXSZ + 1];
	struct index_state *istate = revs->diffopt.repo->index;

	if (revs->pending.nr != 1)
		BUG("run_diff_index must be passed exactly one tree");

	trace_performance_enter();
	ent = revs->pending.objects;

	refresh_fsmonitor(istate);

	if (merge_base) {
		diff_get_merge_base(revs, &oid);
		name = oid_to_hex_r(merge_base_hex, &oid);
	} else {
		oidcpy(&oid, &ent->item->oid);
		name = ent->name;
	}

	if (diff_cache(revs, &oid, name, cached))
		exit(128);

	diff_set_mnemonic_prefix(&revs->diffopt, "c/", cached ? "i/" : "w/");
	diffcore_fix_diff_index();
	diffcore_std(&revs->diffopt);
	diff_flush(&revs->diffopt);
	trace_performance_leave("diff-index");
}

int do_diff_cache(const struct object_id *tree_oid, struct diff_options *opt)
{
	struct rev_info revs;

	repo_init_revisions(opt->repo, &revs, NULL);
	copy_pathspec(&revs.prune_data, &opt->pathspec);
	diff_free(&revs.diffopt);
	revs.diffopt = *opt;
	revs.diffopt.no_free = 1;

	if (diff_cache(&revs, tree_oid, NULL, 1))
		exit(128);

	release_revisions(&revs);
	return 0;
}

int index_differs_from(struct repository *r,
		       const char *def, const struct diff_flags *flags,
		       int ita_invisible_in_index)
{
	struct rev_info rev;
	struct setup_revision_opt opt;
	unsigned has_changes;

	repo_init_revisions(r, &rev, NULL);
	memset(&opt, 0, sizeof(opt));
	opt.def = def;
	setup_revisions(0, NULL, &rev, &opt);
	rev.diffopt.flags.quick = 1;
	rev.diffopt.flags.exit_with_status = 1;
	if (flags) {
		diff_flags_or(&rev.diffopt.flags, flags);
		/*
		 * Now that flags are merged, honor override_submodule_config
		 * and ignore_submodules from passed flags.
		 */
		if (flags->override_submodule_config)
			rev.diffopt.flags.ignore_submodules = flags->ignore_submodules;
	}
	rev.diffopt.ita_invisible_in_index = ita_invisible_in_index;
	run_diff_index(&rev, DIFF_INDEX_CACHED);
	has_changes = rev.diffopt.flags.has_changes;
	release_revisions(&rev);
	return (has_changes != 0);
}

static const char *idiff_prefix_cb(struct diff_options *opt UNUSED, void *data)
{
	return data;
}

void show_interdiff(const struct object_id *oid1, const struct object_id *oid2,
		    int indent, struct diff_options *diffopt)
{
	struct diff_options opts;
	struct strbuf prefix = STRBUF_INIT;

	memcpy(&opts, diffopt, sizeof(opts));
	opts.output_format = DIFF_FORMAT_PATCH;
	opts.output_prefix = idiff_prefix_cb;
	strbuf_addchars(&prefix, ' ', indent);
	opts.output_prefix_data = prefix.buf;
	diff_setup_done(&opts);

	diff_tree_oid(oid1, oid2, "", &opts);
	diffcore_std(&opts);
	diff_flush(&opts);

	strbuf_release(&prefix);
}
