/*
 * Copyright (C) the libgit2 contributors. All rights reserved.
 *
 * This file is part of libgit2, distributed under the GNU GPL v2 with
 * a Linking Exception. For full terms see the included COPYING file.
 */

#include "common.h"
#include "fileops.h"
#include "repository.h"
#include "config.h"
#include "git2/config.h"
#include "vector.h"
#include "filter.h"

struct map_data {
	const char *cvar_name;
	git_cvar_map *maps;
	size_t map_count;
	int default_value;
};

/*
 *	core.eol
 *		Sets the line ending type to use in the working directory for
 *	files that have the text property set. Alternatives are lf, crlf
 *	and native, which uses the platform's native line ending. The default
 *	value is native. See gitattributes(5) for more information on
 *	end-of-line conversion.
 */
static git_cvar_map _cvar_map_eol[] = {
	{GIT_CVAR_FALSE, NULL, GIT_EOL_UNSET},
	{GIT_CVAR_STRING, "lf", GIT_EOL_LF},
	{GIT_CVAR_STRING, "crlf", GIT_EOL_CRLF},
	{GIT_CVAR_STRING, "native", GIT_EOL_NATIVE}
};

/*
 *	core.autocrlf
 *		Setting this variable to "true" is almost the same as setting
 *	the text attribute to "auto" on all files except that text files are
 *	not guaranteed to be normalized: files that contain CRLF in the
 *	repository will not be touched. Use this setting if you want to have
 *	CRLF line endings in your working directory even though the repository
 *	does not have normalized line endings. This variable can be set to input,
 *	in which case no output conversion is performed.
 */
static git_cvar_map _cvar_map_autocrlf[] = {
	{GIT_CVAR_FALSE, NULL, GIT_AUTO_CRLF_FALSE},
	{GIT_CVAR_TRUE, NULL, GIT_AUTO_CRLF_TRUE},
	{GIT_CVAR_STRING, "input", GIT_AUTO_CRLF_INPUT}
};

static git_cvar_map _cvar_map_safecrlf[] = {
	{GIT_CVAR_FALSE, NULL, GIT_SAFE_CRLF_FALSE},
	{GIT_CVAR_TRUE, NULL, GIT_SAFE_CRLF_FAIL},
	{GIT_CVAR_STRING, "warn", GIT_SAFE_CRLF_WARN}
};

/*
 * Generic map for integer values
 */
static git_cvar_map _cvar_map_int[] = {
	{GIT_CVAR_INT32, NULL, 0},
};

static struct map_data _cvar_maps[] = {
	{"core.autocrlf", _cvar_map_autocrlf, ARRAY_SIZE(_cvar_map_autocrlf), GIT_AUTO_CRLF_DEFAULT},
	{"core.eol", _cvar_map_eol, ARRAY_SIZE(_cvar_map_eol), GIT_EOL_DEFAULT},
	{"core.symlinks", NULL, 0, GIT_SYMLINKS_DEFAULT },
	{"core.ignorecase", NULL, 0, GIT_IGNORECASE_DEFAULT },
	{"core.filemode", NULL, 0, GIT_FILEMODE_DEFAULT },
	{"core.ignorestat", NULL, 0, GIT_IGNORESTAT_DEFAULT },
	{"core.trustctime", NULL, 0, GIT_TRUSTCTIME_DEFAULT },
	{"core.abbrev", _cvar_map_int, 1, GIT_ABBREV_DEFAULT },
	{"core.precomposeunicode", NULL, 0, GIT_PRECOMPOSE_DEFAULT },
	{"core.safecrlf", _cvar_map_safecrlf, ARRAY_SIZE(_cvar_map_safecrlf), GIT_SAFE_CRLF_DEFAULT},
	{"core.logallrefupdates", NULL, 0, GIT_LOGALLREFUPDATES_DEFAULT },
	{"core.protecthfs", NULL, 0, GIT_PROTECTHFS_DEFAULT },
	{"core.protectntfs", NULL, 0, GIT_PROTECTNTFS_DEFAULT },
	{"core.fsyncobjectfiles", NULL, 0, GIT_FSYNCOBJECTFILES_DEFAULT },
};

int git_config__cvar(int *out, git_config *config, git_cvar_cached cvar)
{
	int error = 0;
	struct map_data *data = &_cvar_maps[(int)cvar];
	git_config_entry *entry;

	if ((error = git_config__lookup_entry(&entry, config, data->cvar_name, false)) < 0)
		return error;

	if (!entry)
		*out = data->default_value;
	else if (data->maps)
		error = git_config_lookup_map_value(
			out, data->maps, data->map_count, entry->value);
	else
		error = git_config_parse_bool(out, entry->value);

	git_config_entry_free(entry);
	return error;
}

int git_repository__cvar(int *out, git_repository *repo, git_cvar_cached cvar)
{
	*out = repo->cvar_cache[(int)cvar];

	if (*out == GIT_CVAR_NOT_CACHED) {
		int error;
		git_config *config;

		if ((error = git_repository_config__weakptr(&config, repo)) < 0 ||
			(error = git_config__cvar(out, config, cvar)) < 0)
			return error;

		repo->cvar_cache[(int)cvar] = *out;
	}

	return 0;
}

void git_repository__cvar_cache_clear(git_repository *repo)
{
	int i;

	for (i = 0; i < GIT_CVAR_CACHE_MAX; ++i)
		repo->cvar_cache[i] = GIT_CVAR_NOT_CACHED;
}

