#include "builtin.h"
#include "cache.h"

static const char git_config_set_usage[] =
"git-config [ --global ] [ --bool | --int ] [--get | --get-all | --get-regexp | --replace-all | --add | --unset | --unset-all] name [value [value_regex]] | --rename-section old_name new_name | --remove-section name | --list";

static char *key;
static regex_t *key_regexp;
static regex_t *regexp;
static int show_keys;
static int use_key_regexp;
static int do_all;
static int do_not_match;
static int seen;
static enum { T_RAW, T_INT, T_BOOL } type = T_RAW;

static int show_all_config(const char *key_, const char *value_)
{
	if (value_)
		printf("%s=%s\n", key_, value_);
	else
		printf("%s\n", key_);
	return 0;
}

static int show_config(const char* key_, const char* value_)
{
	char value[256];
	const char *vptr = value;
	int dup_error = 0;

	if (!use_key_regexp && strcmp(key_, key))
		return 0;
	if (use_key_regexp && regexec(key_regexp, key_, 0, NULL, 0))
		return 0;
	if (regexp != NULL &&
			 (do_not_match ^
			  regexec(regexp, (value_?value_:""), 0, NULL, 0)))
		return 0;

	if (show_keys)
		printf("%s ", key_);
	if (seen && !do_all)
		dup_error = 1;
	if (type == T_INT)
		sprintf(value, "%d", git_config_int(key_, value_?value_:""));
	else if (type == T_BOOL)
		vptr = git_config_bool(key_, value_) ? "true" : "false";
	else
		vptr = value_?value_:"";
	seen++;
	if (dup_error) {
		error("More than one value for the key %s: %s",
				key_, vptr);
	}
	else
		printf("%s\n", vptr);

	return 0;
}

static int get_value(const char* key_, const char* regex_)
{
	int ret = -1;
	char *tl;
	char *global = NULL, *repo_config = NULL;
	const char *system_wide = NULL, *local;

	local = getenv(CONFIG_ENVIRONMENT);
	if (!local) {
		const char *home = getenv("HOME");
		local = getenv(CONFIG_LOCAL_ENVIRONMENT);
		if (!local)
			local = repo_config = xstrdup(git_path("config"));
		if (home)
			global = xstrdup(mkpath("%s/.gitconfig", home));
		system_wide = ETC_GITCONFIG;
	}

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

	if (use_key_regexp) {
		key_regexp = (regex_t*)xmalloc(sizeof(regex_t));
		if (regcomp(key_regexp, key, REG_EXTENDED)) {
			fprintf(stderr, "Invalid key pattern: %s\n", key_);
			goto free_strings;
		}
	}

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

		regexp = (regex_t*)xmalloc(sizeof(regex_t));
		if (regcomp(regexp, regex_, REG_EXTENDED)) {
			fprintf(stderr, "Invalid pattern: %s\n", regex_);
			goto free_strings;
		}
	}

	if (do_all && system_wide)
		git_config_from_file(show_config, system_wide);
	if (do_all && global)
		git_config_from_file(show_config, global);
	git_config_from_file(show_config, local);
	if (!do_all && !seen && global)
		git_config_from_file(show_config, global);
	if (!do_all && !seen && system_wide)
		git_config_from_file(show_config, system_wide);

	free(key);
	if (regexp) {
		regfree(regexp);
		free(regexp);
	}

	if (do_all)
		ret = !seen;
	else
		ret = (seen == 1) ? 0 : seen > 1 ? 2 : 1;

free_strings:
	free(repo_config);
	free(global);
	return ret;
}

int cmd_config(int argc, const char **argv, const char *prefix)
{
	int nongit = 0;
	setup_git_directory_gently(&nongit);

	while (1 < argc) {
		if (!strcmp(argv[1], "--int"))
			type = T_INT;
		else if (!strcmp(argv[1], "--bool"))
			type = T_BOOL;
		else if (!strcmp(argv[1], "--list") || !strcmp(argv[1], "-l"))
			return git_config(show_all_config);
		else if (!strcmp(argv[1], "--global")) {
			char *home = getenv("HOME");
			if (home) {
				char *user_config = xstrdup(mkpath("%s/.gitconfig", home));
				setenv("GIT_CONFIG", user_config, 1);
				free(user_config);
			} else {
				die("$HOME not set");
			}
		}
		else if (!strcmp(argv[1], "--system"))
			setenv("GIT_CONFIG", ETC_GITCONFIG, 1);
		else if (!strcmp(argv[1], "--rename-section")) {
			int ret;
			if (argc != 4)
				usage(git_config_set_usage);
			ret = git_config_rename_section(argv[2], argv[3]);
			if (ret < 0)
				return ret;
			if (ret == 0) {
				fprintf(stderr, "No such section!\n");
				return 1;
			}
			return 0;
		}
		else if (!strcmp(argv[1], "--remove-section")) {
			int ret;
			if (argc != 3)
				usage(git_config_set_usage);
			ret = git_config_rename_section(argv[2], NULL);
			if (ret < 0)
				return ret;
			if (ret == 0) {
				fprintf(stderr, "No such section!\n");
				return 1;
			}
			return 0;
		}
		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 if (!strcmp(argv[1], "--get-regexp")) {
			show_keys = 1;
			use_key_regexp = 1;
			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], "--get-regexp")) {
			show_keys = 1;
			use_key_regexp = 1;
			do_all = 1;
			return get_value(argv[2], argv[3]);
		} else if (!strcmp(argv[1], "--add"))
			return git_config_set_multivar(argv[2], argv[3], "^$", 0);
		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;
}
