#include "cache.h"
#include <regex.h>

static const char git_config_set_usage[] =
"git-repo-config [ --bool | --int ] [--get | --get-all | --replace-all | --unset | --unset-all] name [value [value_regex]]";

static char* key = NULL;
static char* value = NULL;
static regex_t* regexp = NULL;
static int do_all = 0;
static int do_not_match = 0;
static int seen = 0;
static enum { T_RAW, T_INT, T_BOOL } type = T_RAW;

static int show_config(const char* key_, const char* value_)
{
	if (value_ == NULL)
		value_ = "";

	if (!strcmp(key_, key) &&
			(regexp == NULL ||
			 (do_not_match ^
			  !regexec(regexp, value_, 0, NULL, 0)))) {
		if (do_all) {
			printf("%s\n", value_);
			return 0;
		}
		if (seen > 0) {
			fprintf(stderr, "More than one value: %s\n", value);
			free(value);
		}

		if (type == T_INT) {
			value = malloc(256);
			sprintf(value, "%d", git_config_int(key_, value_));
		} else if (type == T_BOOL) {
			value = malloc(256);
			sprintf(value, "%s", git_config_bool(key_, value_)
					     ? "true" : "false");
		} else {
			value = strdup(value_);
		}
		seen++;
	}
	return 0;
}

static int get_value(const char* key_, const char* regex_)
{
	int i;
	char *tl;

	key = strdup(key_);
	for (tl=key+strlen(key)-1; tl >= key && *tl != '.'; --tl)
		*tl = tolower(*tl);
	for (tl=key; *tl && *tl != '.'; ++tl)
		*tl = tolower(*tl);

	if (regex_) {
		if (regex_[0] == '!') {
			do_not_match = 1;
			regex_++;
		}

		regexp = (regex_t*)malloc(sizeof(regex_t));
		if (regcomp(regexp, regex_, REG_EXTENDED)) {
			fprintf(stderr, "Invalid pattern: %s\n", regex_);
			return -1;
		}
	}

	i = git_config(show_config);
	if (value) {
		printf("%s\n", value);
		free(value);
	}
	free(key);
	if (regexp) {
		regfree(regexp);
		free(regexp);
	}

	if (do_all)
		return 0;

	return seen == 1 ? 0 : 1;
}

int main(int argc, const char **argv)
{
	setup_git_directory();

	while (1 < argc) {
		if (!strcmp(argv[1], "--int"))
			type = T_INT;
		else if (!strcmp(argv[1], "--bool"))
			type = T_BOOL;
		else
			break;
		argc--;
		argv++;
	}

	switch (argc) {
	case 2:
		return get_value(argv[1], NULL);
	case 3:
		if (!strcmp(argv[1], "--unset"))
			return git_config_set(argv[2], NULL);
		else if (!strcmp(argv[1], "--unset-all"))
			return git_config_set_multivar(argv[2], NULL, NULL, 1);
		else if (!strcmp(argv[1], "--get"))
			return get_value(argv[2], NULL);
		else if (!strcmp(argv[1], "--get-all")) {
			do_all = 1;
			return get_value(argv[2], NULL);
		} else

			return git_config_set(argv[1], argv[2]);
	case 4:
		if (!strcmp(argv[1], "--unset"))
			return git_config_set_multivar(argv[2], NULL, argv[3], 0);
		else if (!strcmp(argv[1], "--unset-all"))
			return git_config_set_multivar(argv[2], NULL, argv[3], 1);
		else if (!strcmp(argv[1], "--get"))
			return get_value(argv[2], argv[3]);
		else if (!strcmp(argv[1], "--get-all")) {
			do_all = 1;
			return get_value(argv[2], argv[3]);
		} else if (!strcmp(argv[1], "--replace-all"))

			return git_config_set_multivar(argv[2], argv[3], NULL, 1);
		else

			return git_config_set_multivar(argv[1], argv[2], argv[3], 0);
	case 5:
		if (!strcmp(argv[1], "--replace-all"))
			return git_config_set_multivar(argv[2], argv[3], argv[4], 1);
	case 1:
	default:
		usage(git_config_set_usage);
	}
	return 0;
}
