/*
 * Copyright (c) 2010 Ævar Arnfjörð Bjarmason
 */

#include "cache.h"
#include "exec-cmd.h"
#include "gettext.h"
#include "strbuf.h"
#include "utf8.h"
#include "config.h"

#ifndef NO_GETTEXT
#	include <locale.h>
#	include <libintl.h>
#	ifdef GIT_WINDOWS_NATIVE

static const char *locale_charset(void)
{
	const char *env = getenv("LC_ALL"), *dot;

	if (!env || !*env)
		env = getenv("LC_CTYPE");
	if (!env || !*env)
		env = getenv("LANG");

	if (!env)
		return "UTF-8";

	dot = strchr(env, '.');
	return !dot ? env : dot + 1;
}

#	elif defined HAVE_LIBCHARSET_H
#		include <libcharset.h>
#	else
#		include <langinfo.h>
#		define locale_charset() nl_langinfo(CODESET)
#	endif
#endif

static const char *charset;

/*
 * Guess the user's preferred languages from the value in LANGUAGE environment
 * variable and LC_MESSAGES locale category if NO_GETTEXT is not defined.
 *
 * The result can be a colon-separated list like "ko:ja:en".
 */
const char *get_preferred_languages(void)
{
	const char *retval;

	retval = getenv("LANGUAGE");
	if (retval && *retval)
		return retval;

#ifndef NO_GETTEXT
	retval = setlocale(LC_MESSAGES, NULL);
	if (retval && *retval &&
		strcmp(retval, "C") &&
		strcmp(retval, "POSIX"))
		return retval;
#endif

	return NULL;
}

#ifndef NO_GETTEXT
static int test_vsnprintf(const char *fmt, ...)
{
	char buf[26];
	int ret;
	va_list ap;
	va_start(ap, fmt);
	ret = vsnprintf(buf, sizeof(buf), fmt, ap);
	va_end(ap);
	return ret;
}

static void init_gettext_charset(const char *domain)
{
	setlocale(LC_CTYPE, "");
	charset = locale_charset();
	bind_textdomain_codeset(domain, charset);

	/*
	 * Work around an old bug fixed in glibc 2.17 (released on
	 * 2012-12-24), at the cost of potentially making translated
	 * messages from external functions like perror() emitted in
	 * the wrong encoding.
	 *
	 * The bug affected e.g. git.git's own 7eb93c89651 ([PATCH]
	 * Simplify git script, 2005-09-07), which is the origin of
	 * the "David_K\345gedal" test string.
	 *
	 * See a much longer comment added to this file in 5e9637c6297
	 * (i18n: add infrastructure for translating Git with gettext,
	 * 2011-11-18) for more details.
	 */
	if (test_vsnprintf("%.*s", 13, "David_K\345gedal") < 0)
		setlocale(LC_CTYPE, "C");
}

void git_setup_gettext(void)
{
	const char *podir = getenv(GIT_TEXT_DOMAIN_DIR_ENVIRONMENT);
	char *p = NULL;

	if (!podir)
		podir = p = system_path(GIT_LOCALE_PATH);

	if (!is_directory(podir)) {
		free(p);
		return;
	}

	bindtextdomain("git", podir);
	setlocale(LC_MESSAGES, "");
	setlocale(LC_TIME, "");
	init_gettext_charset("git");
	textdomain("git");

	free(p);
}

/* return the number of columns of string 's' in current locale */
int gettext_width(const char *s)
{
	static int is_utf8 = -1;
	if (is_utf8 == -1)
		is_utf8 = is_utf8_locale();

	return is_utf8 ? utf8_strwidth(s) : strlen(s);
}
#endif

int is_utf8_locale(void)
{
#ifdef NO_GETTEXT
	if (!charset) {
		const char *env = getenv("LC_ALL");
		if (!env || !*env)
			env = getenv("LC_CTYPE");
		if (!env || !*env)
			env = getenv("LANG");
		if (!env)
			env = "";
		if (strchr(env, '.'))
			env = strchr(env, '.') + 1;
		charset = xstrdup(env);
	}
#endif
	return is_encoding_utf8(charset);
}
