/*
 * libgit2 "rev-parse" example - shows how to parse revspecs
 *
 * 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"

/** Forward declarations for helpers. */
struct parse_state {
	git_repository *repo;
	const char *repodir;
	const char *spec;
	int not;
};
static void parse_opts(struct parse_state *ps, int argc, char *argv[]);
static int parse_revision(struct parse_state *ps);


int main(int argc, char *argv[])
{
	struct parse_state ps = {0};

	git_libgit2_init();
	parse_opts(&ps, argc, argv);

	check_lg2(parse_revision(&ps), "Parsing", NULL);

	git_repository_free(ps.repo);
	git_libgit2_shutdown();

	return 0;
}

static void usage(const char *message, const char *arg)
{
	if (message && arg)
		fprintf(stderr, "%s: %s\n", message, arg);
	else if (message)
		fprintf(stderr, "%s\n", message);
	fprintf(stderr, "usage: rev-parse [ --option ] <args>...\n");
	exit(1);
}

static void parse_opts(struct parse_state *ps, int argc, char *argv[])
{
	struct args_info args = ARGS_INFO_INIT;

	for (args.pos=1; args.pos < argc; ++args.pos) {
		const char *a = argv[args.pos];

		if (a[0] != '-') {
			if (ps->spec)
				usage("Too many specs", a);
			ps->spec = a;
		} else if (!strcmp(a, "--not"))
			ps->not = !ps->not;
		else if (!match_str_arg(&ps->repodir, &args, "--git-dir"))
			usage("Cannot handle argument", a);
	}
}

static int parse_revision(struct parse_state *ps)
{
	git_revspec rs;
	char str[GIT_OID_HEXSZ + 1];

	if (!ps->repo) {
		if (!ps->repodir)
			ps->repodir = ".";
		check_lg2(git_repository_open_ext(&ps->repo, ps->repodir, 0, NULL),
			"Could not open repository from", ps->repodir);
	}

	check_lg2(git_revparse(&rs, ps->repo, ps->spec), "Could not parse", ps->spec);

	if ((rs.flags & GIT_REVPARSE_SINGLE) != 0) {
		git_oid_tostr(str, sizeof(str), git_object_id(rs.from));
		printf("%s\n", str);
		git_object_free(rs.from);
	}
	else if ((rs.flags & GIT_REVPARSE_RANGE) != 0) {
		git_oid_tostr(str, sizeof(str), git_object_id(rs.to));
		printf("%s\n", str);
		git_object_free(rs.to);

		if ((rs.flags & GIT_REVPARSE_MERGE_BASE) != 0) {
			git_oid base;
			check_lg2(git_merge_base(&base, ps->repo,
						git_object_id(rs.from), git_object_id(rs.to)),
					"Could not find merge base", ps->spec);

			git_oid_tostr(str, sizeof(str), &base);
			printf("%s\n", str);
		}

		git_oid_tostr(str, sizeof(str), git_object_id(rs.from));
		printf("^%s\n", str);
		git_object_free(rs.from);
	}
	else {
		fatal("Invalid results from git_revparse", ps->spec);
	}

	return 0;
}

