/*
 * libgit2 "blame" example - shows how to use the blame API
 *
 * Written by the libgit2 contributors
 *
 * To the extent possible under law, the author(s) have dedicated all copyright
 * and related and neighboring rights to this software to the public domain
 * worldwide. This software is distributed without any warranty.
 *
 * You should have received a copy of the CC0 Public Domain Dedication along
 * with this software. If not, see
 * <http://creativecommons.org/publicdomain/zero/1.0/>.
 */

#include "common.h"

#ifdef _MSC_VER
#define snprintf sprintf_s
#define strcasecmp strcmpi
#endif

/**
 * This example demonstrates how to invoke the libgit2 blame API to roughly
 * simulate the output of `git blame` and a few of its command line arguments.
 */

struct opts {
	char *path;
	char *commitspec;
	int C;
	int M;
	int start_line;
	int end_line;
	int F;
};
static void parse_opts(struct opts *o, int argc, char *argv[]);

int main(int argc, char *argv[])
{
	int line, break_on_null_hunk;
	size_t i, rawsize;
	char spec[1024] = {0};
	struct opts o = {0};
	const char *rawdata;
	git_repository *repo = NULL;
	git_revspec revspec = {0};
	git_blame_options blameopts = GIT_BLAME_OPTIONS_INIT;
	git_blame *blame = NULL;
	git_blob *blob;
	git_object *obj;

	git_libgit2_init();

	parse_opts(&o, argc, argv);
	if (o.M) blameopts.flags |= GIT_BLAME_TRACK_COPIES_SAME_COMMIT_MOVES;
	if (o.C) blameopts.flags |= GIT_BLAME_TRACK_COPIES_SAME_COMMIT_COPIES;
	if (o.F) blameopts.flags |= GIT_BLAME_FIRST_PARENT;

	/** Open the repository. */
	check_lg2(git_repository_open_ext(&repo, ".", 0, NULL), "Couldn't open repository", NULL);

	/**
	 * The commit range comes in "commitish" form. Use the rev-parse API to
	 * nail down the end points.
	 */
	if (o.commitspec) {
		check_lg2(git_revparse(&revspec, repo, o.commitspec), "Couldn't parse commit spec", NULL);
		if (revspec.flags & GIT_REVPARSE_SINGLE) {
			git_oid_cpy(&blameopts.newest_commit, git_object_id(revspec.from));
			git_object_free(revspec.from);
		} else {
			git_oid_cpy(&blameopts.oldest_commit, git_object_id(revspec.from));
			git_oid_cpy(&blameopts.newest_commit, git_object_id(revspec.to));
			git_object_free(revspec.from);
			git_object_free(revspec.to);
		}
	}

	/** Run the blame. */
	check_lg2(git_blame_file(&blame, repo, o.path, &blameopts), "Blame error", NULL);

	/**
	 * Get the raw data inside the blob for output. We use the
	 * `commitish:path/to/file.txt` format to find it.
	 */
	if (git_oid_iszero(&blameopts.newest_commit))
		strcpy(spec, "HEAD");
	else
		git_oid_tostr(spec, sizeof(spec), &blameopts.newest_commit);
	strcat(spec, ":");
	strcat(spec, o.path);

	check_lg2(git_revparse_single(&obj, repo, spec), "Object lookup error", NULL);
	check_lg2(git_blob_lookup(&blob, repo, git_object_id(obj)), "Blob lookup error", NULL);
	git_object_free(obj);

	rawdata = git_blob_rawcontent(blob);
	rawsize = git_blob_rawsize(blob);

	/** Produce the output. */
	line = 1;
	i = 0;
	break_on_null_hunk = 0;
	while (i < rawsize) {
		const char *eol = memchr(rawdata + i, '\n', rawsize - i);
		char oid[10] = {0};
		const git_blame_hunk *hunk = git_blame_get_hunk_byline(blame, line);

		if (break_on_null_hunk && !hunk)
			break;

		if (hunk) {
			char sig[128] = {0};
			break_on_null_hunk = 1;
			
			git_oid_tostr(oid, 10, &hunk->final_commit_id);
			snprintf(sig, 30, "%s <%s>", hunk->final_signature->name, hunk->final_signature->email);

			printf("%s ( %-30s %3d) %.*s\n",
					oid,
					sig,
					line,
					(int)(eol - rawdata - i),
					rawdata + i);
		}

		i = (int)(eol - rawdata + 1);
		line++;
	}

	/** Cleanup. */
	git_blob_free(blob);
	git_blame_free(blame);
	git_repository_free(repo);

	git_libgit2_shutdown();

	return 0;
}

/** Tell the user how to make this thing work. */
static void usage(const char *msg, const char *arg)
{
	if (msg && arg)
		fprintf(stderr, "%s: %s\n", msg, arg);
	else if (msg)
		fprintf(stderr, "%s\n", msg);
	fprintf(stderr, "usage: blame [options] [<commit range>] <path>\n");
	fprintf(stderr, "\n");
	fprintf(stderr, "   <commit range>      example: `HEAD~10..HEAD`, or `1234abcd`\n");
	fprintf(stderr, "   -L <n,m>            process only line range n-m, counting from 1\n");
	fprintf(stderr, "   -M                  find line moves within and across files\n");
	fprintf(stderr, "   -C                  find line copies within and across files\n");
	fprintf(stderr, "   -F                  follow only the first parent commits\n");
	fprintf(stderr, "\n");
	exit(1);
}

/** Parse the arguments. */
static void parse_opts(struct opts *o, int argc, char *argv[])
{
	int i;
	char *bare_args[3] = {0};

	if (argc < 2) usage(NULL, NULL);

	for (i=1; i<argc; i++) {
		char *a = argv[i];

		if (a[0] != '-') {
			int i=0;
			while (bare_args[i] && i < 3) ++i;
			if (i >= 3)
				usage("Invalid argument set", NULL);
			bare_args[i] = a;
		}
		else if (!strcmp(a, "--"))
			continue;
		else if (!strcasecmp(a, "-M"))
			o->M = 1;
		else if (!strcasecmp(a, "-C"))
			o->C = 1;
		else if (!strcasecmp(a, "-F"))
			o->F = 1;
		else if (!strcasecmp(a, "-L")) {
			i++; a = argv[i];
			if (i >= argc) fatal("Not enough arguments to -L", NULL);
			check_lg2(sscanf(a, "%d,%d", &o->start_line, &o->end_line)-2, "-L format error", NULL);
		}
		else {
			/* commit range */
			if (o->commitspec) fatal("Only one commit spec allowed", NULL);
			o->commitspec = a;
		}
	}

	/* Handle the bare arguments */
	if (!bare_args[0]) usage("Please specify a path", NULL);
	o->path = bare_args[0];
	if (bare_args[1]) {
		/* <commitspec> <path> */
		o->path = bare_args[1];
		o->commitspec = bare_args[0];
	}
	if (bare_args[2]) {
		/* <oldcommit> <newcommit> <path> */
		char spec[128] = {0};
		o->path = bare_args[2];
		sprintf(spec, "%s..%s", bare_args[0], bare_args[1]);
		o->commitspec = spec;
	}
}
