#-*- coding:utf-8 -*-
# Copyright 2015 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
"""
Function to check whether the current used LC_CTYPE handles case
transformations of ASCII characters in a way compatible with the POSIX
locale.
"""
from __future__ import absolute_import, unicode_literals

import locale
import logging
import os
import textwrap
import traceback

import portage
from portage.util import _unicode_decode, writemsg_level
from portage.util._ctypes import find_library, LoadLibrary


locale_categories = (
	'LC_COLLATE', 'LC_CTYPE', 'LC_MONETARY', 'LC_MESSAGES',
	'LC_NUMERIC', 'LC_TIME',
	# GNU extensions
	'LC_ADDRESS', 'LC_IDENTIFICATION', 'LC_MEASUREMENT', 'LC_NAME',
	'LC_PAPER', 'LC_TELEPHONE',
)

_check_locale_cache = {}


def _check_locale(silent):
	"""
	The inner locale check function.
	"""
	try:
		from portage.util import libc
	except ImportError:
		libc_fn = find_library("c")
		if libc_fn is None:
			return None
		libc = LoadLibrary(libc_fn)
		if libc is None:
			return None

	lc = list(range(ord('a'), ord('z')+1))
	uc = list(range(ord('A'), ord('Z')+1))
	rlc = [libc.tolower(c) for c in uc]
	ruc = [libc.toupper(c) for c in lc]

	if lc != rlc or uc != ruc:
		if silent:
			return False

		msg = ("WARNING: The LC_CTYPE variable is set to a locale " +
			"that specifies transformation between lowercase " +
			"and uppercase ASCII characters that is different than " +
			"the one specified by POSIX locale. This can break " +
			"ebuilds and cause issues in programs that rely on " +
			"the common character conversion scheme. " +
			"Please consider enabling another locale (such as " +
			"en_US.UTF-8) in /etc/locale.gen and setting it " +
			"as LC_CTYPE in make.conf.")
		msg = [l for l in textwrap.wrap(msg, 70)]
		msg.append("")
		chars = lambda l: ''.join(_unicode_decode(chr(x)) for x in l)
		if uc != ruc:
			msg.extend([
				"  %s -> %s" % (chars(lc), chars(ruc)),
				"  %28s: %s" % ('expected', chars(uc))])
		if lc != rlc:
			msg.extend([
				"  %s -> %s" % (chars(uc), chars(rlc)),
				"  %28s: %s" % ('expected', chars(lc))])
		writemsg_level("".join(["!!! %s\n" % l for l in msg]),
			level=logging.ERROR, noiselevel=-1)
		return False

	return True


def check_locale(silent=False, env=None):
	"""
	Check whether the locale is sane. Returns True if it is, prints
	warning and returns False if it is not. Returns None if the check
	can not be executed due to platform limitations.
	"""

	if env is not None:
		for v in ("LC_ALL", "LC_CTYPE", "LANG"):
			if v in env:
				mylocale = env[v]
				break
		else:
			mylocale = "C"

		try:
			return _check_locale_cache[mylocale]
		except KeyError:
			pass

	pid = os.fork()
	if pid == 0:
		try:
			if env is not None:
				try:
					locale.setlocale(locale.LC_CTYPE,
						portage._native_string(mylocale))
				except locale.Error:
					os._exit(2)

			ret = _check_locale(silent)
			if ret is None:
				os._exit(2)
			else:
				os._exit(0 if ret else 1)
		except Exception:
			traceback.print_exc()
			os._exit(2)

	pid2, ret = os.waitpid(pid, 0)
	assert pid == pid2
	pyret = None
	if os.WIFEXITED(ret):
		ret = os.WEXITSTATUS(ret)
		if ret != 2:
			pyret = ret == 0

	if env is not None:
		_check_locale_cache[mylocale] = pyret
	return pyret


def split_LC_ALL(env):
	"""
	Replace LC_ALL with split-up LC_* variables if it is defined.
	Works on the passed environment (or settings instance).
	"""
	lc_all = env.get("LC_ALL")
	if lc_all is not None:
		for c in locale_categories:
			env[c] = lc_all
		del env["LC_ALL"]
