# elog/messages.py - elog core functions
# Copyright 2006-2011 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2

import portage
portage.proxy.lazyimport.lazyimport(globals(),
	'portage.output:colorize',
	'portage.util:writemsg',
)

from portage.const import EBUILD_PHASES
from portage.localization import _
from portage import os
from portage import _encodings
from portage import _unicode_encode
from portage import _unicode_decode

import io
import sys

_log_levels = frozenset([
	"ERROR",
	"INFO",
	"LOG",
	"QA",
	"WARN",
])

def collect_ebuild_messages(path):
	""" Collect elog messages generated by the bash logging function stored 
		at 'path'.
	"""
	mylogfiles = None
	try:
		mylogfiles = os.listdir(path)
	except OSError:
		pass
	# shortcut for packages without any messages
	if not mylogfiles:
		return {}
	# exploit listdir() file order so we process log entries in chronological order
	mylogfiles.reverse()
	logentries = {}
	for msgfunction in mylogfiles:
		filename = os.path.join(path, msgfunction)
		if msgfunction not in EBUILD_PHASES:
			writemsg(_("!!! can't process invalid log file: %s\n") % filename,
				noiselevel=-1)
			continue
		if not msgfunction in logentries:
			logentries[msgfunction] = []
		lastmsgtype = None
		msgcontent = []
		f = io.open(_unicode_encode(filename,
			encoding=_encodings['fs'], errors='strict'),
			mode='r', encoding=_encodings['repo.content'], errors='replace')
		# Use split('\n') since normal line iteration or readlines() will
		# split on \r characters as shown in bug #390833.
		for l in f.read().split('\n'):
			if not l:
				continue
			try:
				msgtype, msg = l.split(" ", 1)
				if msgtype not in _log_levels:
					raise ValueError(msgtype)
			except ValueError:
				writemsg(_("!!! malformed entry in "
					"log file: '%s': %s\n") % (filename, l), noiselevel=-1)
				continue

			if lastmsgtype is None:
				lastmsgtype = msgtype
			
			if msgtype == lastmsgtype:
				msgcontent.append(msg)
			else:
				if msgcontent:
					logentries[msgfunction].append((lastmsgtype, msgcontent))
				msgcontent = [msg]
			lastmsgtype = msgtype
		f.close()
		if msgcontent:
			logentries[msgfunction].append((lastmsgtype, msgcontent))

	# clean logfiles to avoid repetitions
	for f in mylogfiles:
		try:
			os.unlink(os.path.join(path, f))
		except OSError:
			pass
	return logentries

_msgbuffer = {}
def _elog_base(level, msg, phase="other", key=None, color=None, out=None):
	""" Backend for the other messaging functions, should not be called 
	    directly.
	"""

	# TODO: Have callers pass in a more unique 'key' parameter than a plain
	# cpv, in order to ensure that messages are properly grouped together
	# for a given package instance, and also to ensure that each elog module's
	# process() function is only called once for each unique package. This is
	# needed not only when building packages in parallel, but also to preserve
	# continuity in messages when a package is simply updated, since we don't
	# want the elog_process() call from the uninstall of the old version to
	# cause discontinuity in the elog messages of the new one being installed.

	global _msgbuffer

	if out is None:
		out = sys.stdout

	if color is None:
		color = "GOOD"

	msg = _unicode_decode(msg,
		encoding=_encodings['content'], errors='replace')

	formatted_msg = colorize(color, " * ") + msg + "\n"

	# avoid potential UnicodeEncodeError
	if out in (sys.stdout, sys.stderr):
		formatted_msg = _unicode_encode(formatted_msg,
			encoding=_encodings['stdio'], errors='backslashreplace')
		if sys.hexversion >= 0x3000000:
			out = out.buffer

	out.write(formatted_msg)

	if key not in _msgbuffer:
		_msgbuffer[key] = {}
	if phase not in _msgbuffer[key]:
		_msgbuffer[key][phase] = []
	_msgbuffer[key][phase].append((level, msg))

	#raise NotImplementedError()

def collect_messages(key=None, phasefilter=None):
	global _msgbuffer

	if key is None:
		rValue = _msgbuffer
		_reset_buffer()
	else:
		rValue = {}
		if key in _msgbuffer:
			if phasefilter is None:
				rValue[key] = _msgbuffer.pop(key)
			else:
				rValue[key] = {}
				for phase in phasefilter:
					try:
						rValue[key][phase] = _msgbuffer[key].pop(phase)
					except KeyError:
						pass
				if not _msgbuffer[key]:
					del _msgbuffer[key]
	return rValue

def _reset_buffer():
	""" Reset the internal message buffer when it has been processed, 
	    should not be called directly.
	"""
	global _msgbuffer
	
	_msgbuffer = {}

# creating and exporting the actual messaging functions
_functions = { "einfo": ("INFO", "GOOD"),
		"elog": ("LOG", "GOOD"),
		"ewarn": ("WARN", "WARN"),
		"eqawarn": ("QA", "WARN"),
		"eerror": ("ERROR", "BAD"),
}

class _make_msgfunction(object):
	__slots__ = ('_color', '_level')
	def __init__(self, level, color):
		self._level = level
		self._color = color
	def __call__(self, msg, phase="other", key=None, out=None):
		"""
		Display and log a message assigned to the given key/cpv.
		""" 
		_elog_base(self._level, msg,  phase=phase,
			key=key, color=self._color, out=out)

for f in _functions:
	setattr(sys.modules[__name__], f, _make_msgfunction(_functions[f][0], _functions[f][1]))
del f, _functions
