#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 (!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_ ? value_ : "");
		}
		seen++;
	}
	return 0;
}

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

	key = malloc(strlen(key_)+1);
	for (i = 0; key_[i]; i++)
		key[i] = tolower(key_[i]);
	key[i] = 0;

	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;
}
