/*
 * libgit2 "describe" example - shows how to describe commits
 *
 * 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"
#include <assert.h>

/**
 * The following example partially reimplements the `git describe` command
 * and some of its options.
 *
 * These commands should work:

 * - Describe HEAD with default options (`describe`)
 * - Describe specified revision (`describe master~2`)
 * - Describe specified revisions (`describe master~2 HEAD~3`)
 * - Describe HEAD with dirty state suffix (`describe --dirty=*`)
 * - Describe consider all refs (`describe --all master`)
 * - Describe consider lightweight tags (`describe --tags temp-tag`)
 * - Describe show non-default abbreviated size (`describe --abbrev=10`)
 * - Describe always output the long format if matches a tag (`describe --long v1.0`)
 * - Describe consider only tags of specified pattern (`describe --match v*-release`)
 * - Describe show the fallback result (`describe --always`)
 * - Describe follow only the first parent commit (`describe --first-parent`)
 *
 * The command line parsing logic is simplified and doesn't handle
 * all of the use cases.
 */

/** describe_options represents the parsed command line options */
typedef struct {
	const char **commits;
	size_t commit_count;
	git_describe_options describe_options;
	git_describe_format_options format_options;
} describe_options;

typedef struct args_info args_info;

static void *xrealloc(void *oldp, size_t newsz)
{
	void *p = realloc(oldp, newsz);
	if (p == NULL) {
		fprintf(stderr, "Cannot allocate memory, exiting.\n");
		exit(1);
	}
	return p;
}

static void opts_add_commit(describe_options *opts, const char *commit)
{
	size_t sz;

	assert(opts != NULL);

	sz = ++opts->commit_count * sizeof(opts->commits[0]);
	opts->commits = xrealloc(opts->commits, sz);
	opts->commits[opts->commit_count - 1] = commit;
}

static void do_describe_single(git_repository *repo, describe_options *opts, const char *rev)
{
	git_object *commit;
	git_describe_result *describe_result;
	git_buf buf = { 0 };
	
	if (rev) {
		check_lg2(git_revparse_single(&commit, repo, rev),
			"Failed to lookup rev", rev);

		check_lg2(git_describe_commit(&describe_result, commit, &opts->describe_options),
			"Failed to describe rev", rev);
	}
	else
		check_lg2(git_describe_workdir(&describe_result, repo, &opts->describe_options),
			"Failed to describe workdir", NULL);

	check_lg2(git_describe_format(&buf, describe_result, &opts->format_options),
			"Failed to format describe rev", rev);

	printf("%s\n", buf.ptr);
}

static void do_describe(git_repository *repo, describe_options *opts)
{
	if (opts->commit_count == 0)
		do_describe_single(repo, opts, NULL);
	else
	{
		size_t i;
		for (i = 0; i < opts->commit_count; i++)
			do_describe_single(repo, opts, opts->commits[i]);
	}
}

static void print_usage(void)
{
	fprintf(stderr, "usage: see `git help describe`\n");
	exit(1);
}

/** Parse command line arguments */
static void parse_options(describe_options *opts, int argc, char **argv)
{
	args_info args = ARGS_INFO_INIT;

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

		if (curr[0] != '-') {
			opts_add_commit(opts, curr);
		} else if (!strcmp(curr, "--all")) {
			opts->describe_options.describe_strategy = GIT_DESCRIBE_ALL;
		} else if (!strcmp(curr, "--tags")) {
			opts->describe_options.describe_strategy = GIT_DESCRIBE_TAGS;
		} else if (!strcmp(curr, "--exact-match")) {
			opts->describe_options.max_candidates_tags = 0;
		} else if (!strcmp(curr, "--long")) {
			opts->format_options.always_use_long_format = 1;
		} else if (!strcmp(curr, "--always")) {
			opts->describe_options.show_commit_oid_as_fallback = 1;
		} else if (!strcmp(curr, "--first-parent")) {
			opts->describe_options.only_follow_first_parent = 1;
		} else if (optional_str_arg(&opts->format_options.dirty_suffix, &args, "--dirty", "-dirty")) {
		} else if (match_int_arg((int *)&opts->format_options.abbreviated_size, &args, "--abbrev", 0)) {
		} else if (match_int_arg((int *)&opts->describe_options.max_candidates_tags, &args, "--candidates", 0)) {
		} else if (match_str_arg(&opts->describe_options.pattern, &args, "--match")) {
		}
	}

	if (opts->commit_count > 0) {
		if (opts->format_options.dirty_suffix)
			fatal("--dirty is incompatible with commit-ishes", NULL);
	}
	else {
		if (!opts->format_options.dirty_suffix || !opts->format_options.dirty_suffix[0]) {
			opts_add_commit(opts, "HEAD");
		}
	}
}

/** Initialize describe_options struct */
static void describe_options_init(describe_options *opts)
{
	memset(opts, 0, sizeof(*opts));

	opts->commits = NULL;
	opts->commit_count = 0;
	git_describe_init_options(&opts->describe_options, GIT_DESCRIBE_OPTIONS_VERSION);
	git_describe_init_format_options(&opts->format_options, GIT_DESCRIBE_FORMAT_OPTIONS_VERSION);
}

int main(int argc, char **argv)
{
	git_repository *repo;
	describe_options opts;

	git_libgit2_init();

	check_lg2(git_repository_open_ext(&repo, ".", 0, NULL),
			"Could not open repository", NULL);

	describe_options_init(&opts);
	parse_options(&opts, argc, argv);

	do_describe(repo, &opts);

	git_repository_free(repo);
	git_libgit2_shutdown();

	return 0;
}
