/*
 * 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"

/**
 * 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;
};
static void parse_opts(struct opts *o, int argc, char *argv[]);

int main(int argc, char *argv[])
{
	int i, line, break_on_null_hunk;
	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_threads_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;

	/** 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);

	/** Produce the output. */
	line = 1;
	i = 0;
	break_on_null_hunk = 0;
	while (i < git_blob_rawsize(blob)) {
		const char *eol = strchr(rawdata+i, '\n');
		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) {
			break_on_null_hunk = 1;
			char sig[128] = {0};

			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_threads_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, "\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, "-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;
	}
}
