# Copyright 2010 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
# $Id$

import codecs

_codec_map = None

def _setup_encodings(default_encoding, filesystem_encoding, missing_encodings):
	"""
	The <python-2.6.4 that's inside stage 1 or 2 is built with a minimal
	configuration which does not include the /usr/lib/pythonX.Y/encodings
	directory. This results in error like the following:

	  LookupError: no codec search functions registered: can't find encoding

	In order to solve this problem, detect it early and manually register
	a search function for the ascii and utf_8 codecs. Starting with python-3.0
	this problem is more noticeable because of stricter handling of encoding
	and decoding between strings of characters and bytes.
	"""

	global _codec_map
	_codec_map = _gen_missing_encodings(missing_encodings)

	default_fallback = 'utf_8'

	if default_encoding in missing_encodings and \
		default_encoding not in _codec_map:
		# Make the fallback codec correspond to whatever name happens
		# to be returned by sys.getfilesystemencoding().

		try:
			_codec_map[default_encoding] = codecs.lookup(default_fallback)
		except LookupError:
			_codec_map[default_encoding] = _codec_map[default_fallback]

	if filesystem_encoding in missing_encodings and \
		filesystem_encoding not in _codec_map:
		# Make the fallback codec correspond to whatever name happens
		# to be returned by sys.getdefaultencoding().

		try:
			_codec_map[filesystem_encoding] = codecs.lookup(default_fallback)
		except LookupError:
			_codec_map[filesystem_encoding] = _codec_map[default_fallback]

	codecs.register(_search_function)

def _gen_missing_encodings(missing_encodings):

	codec_map = {}

	if 'ascii' in missing_encodings:

		class AsciiIncrementalEncoder(codecs.IncrementalEncoder):
			def encode(self, input, final=False):
				return codecs.ascii_encode(input, self.errors)[0]

		class AsciiIncrementalDecoder(codecs.IncrementalDecoder):
			def decode(self, input, final=False):
				return codecs.ascii_decode(input, self.errors)[0]

		class AsciiStreamWriter(codecs.StreamWriter):
			encode = codecs.ascii_encode

		class AsciiStreamReader(codecs.StreamReader):
			decode = codecs.ascii_decode

		codec_info =  codecs.CodecInfo(
			name='ascii',
			encode=codecs.ascii_encode,
			decode=codecs.ascii_decode,
			incrementalencoder=AsciiIncrementalEncoder,
			incrementaldecoder=AsciiIncrementalDecoder,
			streamwriter=AsciiStreamWriter,
			streamreader=AsciiStreamReader,
		)

		for alias in ('ascii', '646', 'ansi_x3.4_1968', 'ansi_x3_4_1968',
			'ansi_x3.4_1986', 'cp367', 'csascii', 'ibm367', 'iso646_us',
			'iso_646.irv_1991', 'iso_ir_6', 'us', 'us_ascii'):
			codec_map[alias] = codec_info

	if 'utf_8' in missing_encodings:

		def utf8decode(input, errors='strict'):
			return codecs.utf_8_decode(input, errors, True)

		class Utf8IncrementalEncoder(codecs.IncrementalEncoder):
			def encode(self, input, final=False):
				return codecs.utf_8_encode(input, self.errors)[0]

		class Utf8IncrementalDecoder(codecs.BufferedIncrementalDecoder):
			_buffer_decode = codecs.utf_8_decode

		class Utf8StreamWriter(codecs.StreamWriter):
			encode = codecs.utf_8_encode

		class Utf8StreamReader(codecs.StreamReader):
			decode = codecs.utf_8_decode

		codec_info = codecs.CodecInfo(
			name='utf-8',
			encode=codecs.utf_8_encode,
			decode=utf8decode,
			incrementalencoder=Utf8IncrementalEncoder,
			incrementaldecoder=Utf8IncrementalDecoder,
			streamreader=Utf8StreamReader,
			streamwriter=Utf8StreamWriter,
		)

		for alias in ('utf_8', 'u8', 'utf', 'utf8', 'utf8_ucs2', 'utf8_ucs4'):
			codec_map[alias] = codec_info

	return codec_map

def _search_function(name):
	global _codec_map
	name = name.lower()
	name = name.replace('-', '_')
	codec_info = _codec_map.get(name)
	if codec_info is not None:
		return codecs.CodecInfo(
			name=codec_info.name,
			encode=codec_info.encode,
			decode=codec_info.decode,
			incrementalencoder=codec_info.incrementalencoder,
			incrementaldecoder=codec_info.incrementaldecoder,
			streamreader=codec_info.streamreader,
			streamwriter=codec_info.streamwriter,
		)
	return None
