# Copyright 1999-2010 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2

import gzip
import sys
import tempfile

from _emerge.BinpkgEnvExtractor import BinpkgEnvExtractor
from _emerge.MiscFunctionsProcess import MiscFunctionsProcess
from _emerge.EbuildProcess import EbuildProcess
from _emerge.CompositeTask import CompositeTask
from portage.util import writemsg
from portage.xml.metadata import MetaDataXML
import portage
portage.proxy.lazyimport.lazyimport(globals(),
	'portage.elog:messages@elog_messages',
	'portage.package.ebuild.doebuild:_check_build_log,' + \
		'_post_phase_cmds,_post_phase_userpriv_perms,' + \
		'_post_src_install_chost_fix,' + \
		'_post_src_install_uid_fix'
)
from portage import os
from portage import StringIO
from portage import _encodings
from portage import _unicode_decode
from portage import _unicode_encode

class EbuildPhase(CompositeTask):

	__slots__ = ("actionmap", "phase", "settings")

	def _start(self):

		need_builddir = self.phase not in EbuildProcess._phases_without_builddir

		if need_builddir:
			phase_completed_file = os.path.join(
				self.settings['PORTAGE_BUILDDIR'],
				".%sed" % self.phase.rstrip('e'))
			if not os.path.exists(phase_completed_file):
				# If the phase is really going to run then we want
				# to eliminate any stale elog messages that may
				# exist from a previous run.
				try:
					os.unlink(os.path.join(self.settings['T'],
						'logging', self.phase))
				except OSError:
					pass

		if self.phase == 'setup':

			use = self.settings.get('PORTAGE_BUILT_USE')
			if use is None:
				use = self.settings['PORTAGE_USE']

			maint_str = ""
			metadata_xml_path = os.path.join(os.path.dirname(self.settings['EBUILD']), "metadata.xml")
			if os.path.isfile(metadata_xml_path):
				herds_path = os.path.join(self.settings['PORTDIR'],
					'metadata/herds.xml')
				try:
					metadata_xml = MetaDataXML(metadata_xml_path, herds_path)
					maint_str = metadata_xml.format_maintainer_string()
				except SyntaxError:
					maint_str = "<invalid metadata.xml>"

			msg = []
			msg.append("Package:    %s" % self.settings.mycpv)
			if self.settings.get('PORTAGE_REPO_NAME'):
				msg.append("Repository: %s" % self.settings['PORTAGE_REPO_NAME'])
			if maint_str:
				msg.append("Maintainer: %s" % maint_str)
			msg.append("USE:  %s" % use)
			self._elog('einfo', msg)

		if self.phase == 'package':
			if 'PORTAGE_BINPKG_TMPFILE' not in self.settings:
				self.settings['PORTAGE_BINPKG_TMPFILE'] = \
					os.path.join(self.settings['PKGDIR'],
					self.settings['CATEGORY'], self.settings['PF']) + '.tbz2'

		if self.phase == 'prerm':
			env_extractor = BinpkgEnvExtractor(background=self.background,
				scheduler=self.scheduler, settings=self.settings)
			if env_extractor.saved_env_exists():
				self._start_task(env_extractor, self._env_extractor_exit)
				return
			# If the environment.bz2 doesn't exist, then ebuild.sh will
			# source the ebuild as a fallback.

		self._start_ebuild()

	def _env_extractor_exit(self, env_extractor):
		if self._default_exit(env_extractor) != os.EX_OK:
			self.wait()
			return

		self._start_ebuild()

	def _start_ebuild(self):

		# Don't open the log file during the clean phase since the
		# open file can result in an nfs lock on $T/build.log which
		# prevents the clean phase from removing $T.
		logfile = self.settings.get("PORTAGE_LOG_FILE")
		if self.phase in ("clean", "cleanrm"):
			logfile = None

		fd_pipes = None
		if not self.background and self.phase == 'nofetch':
			# All the pkg_nofetch output goes to stderr since
			# it's considered to be an error message.
			fd_pipes = {1 : sys.stderr.fileno()}

		ebuild_process = EbuildProcess(actionmap=self.actionmap,
			background=self.background, fd_pipes=fd_pipes, logfile=logfile,
			phase=self.phase, scheduler=self.scheduler,
			settings=self.settings)

		self._start_task(ebuild_process, self._ebuild_exit)

	def _ebuild_exit(self, ebuild_process):

		fail = False
		if self._default_exit(ebuild_process) != os.EX_OK:
			if self.phase == "test" and \
				"test-fail-continue" in self.settings.features:
				pass
			else:
				fail = True

		if not fail:
			self.returncode = None

		if self.phase == "install":
			out = portage.StringIO()
			_check_build_log(self.settings, out=out)
			msg = _unicode_decode(out.getvalue(),
				encoding=_encodings['content'], errors='replace')
			self.scheduler.output(msg,
				log_path=self.settings.get("PORTAGE_LOG_FILE"))

		if fail:
			self._die_hooks()
			return

		settings = self.settings
		_post_phase_userpriv_perms(settings)

		if self.phase == "install":
			out = portage.StringIO()
			_post_src_install_chost_fix(settings)
			_post_src_install_uid_fix(settings, out)
			msg = _unicode_decode(out.getvalue(),
				encoding=_encodings['content'], errors='replace')
			if msg:
				self.scheduler.output(msg,
					log_path=self.settings.get("PORTAGE_LOG_FILE"))

		post_phase_cmds = _post_phase_cmds.get(self.phase)
		if post_phase_cmds is not None:
			logfile = settings.get("PORTAGE_LOG_FILE")
			if logfile is not None and self.phase in ("install",):
				# Log to a temporary file, since the code we are running
				# reads PORTAGE_LOG_FILE for QA checks, and we want to
				# avoid annoying "gzip: unexpected end of file" messages
				# when FEATURES=compress-build-logs is enabled.
				fd, logfile = tempfile.mkstemp()
				os.close(fd)
			post_phase = MiscFunctionsProcess(background=self.background,
				commands=post_phase_cmds, logfile=logfile, phase=self.phase,
				scheduler=self.scheduler, settings=settings)
			self._start_task(post_phase, self._post_phase_exit)
			return

		# this point is not reachable if there was a failure and
		# we returned for die_hooks above, so returncode must
		# indicate success (especially if ebuild_process.returncode
		# is unsuccessful and test-fail-continue came into play)
		self.returncode = os.EX_OK
		self._current_task = None
		self.wait()

	def _post_phase_exit(self, post_phase):

		self._assert_current(post_phase)

		log_path = self.settings.get("PORTAGE_LOG_FILE")
		if post_phase.logfile is not None and \
			post_phase.logfile != log_path:
			# We were logging to a temp file (see above), so append
			# temp file to main log and remove temp file.
			self._append_temp_log(post_phase.logfile, log_path)

		if self._final_exit(post_phase) != os.EX_OK:
			writemsg("!!! post %s failed; exiting.\n" % self.phase,
				noiselevel=-1)
			self._die_hooks()
			return
		self._current_task = None
		self.wait()
		return

	def _append_temp_log(self, temp_log, log_path):

		temp_file = open(_unicode_encode(temp_log,
			encoding=_encodings['fs'], errors='strict'), 'rb')

		log_file = self._open_log(log_path)

		for line in temp_file:
			log_file.write(line)

		temp_file.close()
		log_file.close()
		os.unlink(temp_log)

	def _open_log(self, log_path):

		f = open(_unicode_encode(log_path,
			encoding=_encodings['fs'], errors='strict'),
			mode='ab')

		if log_path.endswith('.gz'):
			f =  gzip.GzipFile(filename='', mode='ab', fileobj=f)

		return f

	def _die_hooks(self):
		self.returncode = None
		phase = 'die_hooks'
		die_hooks = MiscFunctionsProcess(background=self.background,
			commands=[phase], phase=phase,
			scheduler=self.scheduler, settings=self.settings)
		self._start_task(die_hooks, self._die_hooks_exit)

	def _die_hooks_exit(self, die_hooks):
		if self.phase != 'clean' and \
			'noclean' not in self.settings.features and \
			'fail-clean' in self.settings.features:
			self._default_exit(die_hooks)
			self._fail_clean()
			return
		self._final_exit(die_hooks)
		self.returncode = 1
		self.wait()

	def _fail_clean(self):
		self.returncode = None
		portage.elog.elog_process(self.settings.mycpv, self.settings)
		phase = "clean"
		clean_phase = EbuildPhase(background=self.background,
			phase=phase, scheduler=self.scheduler, settings=self.settings)
		self._start_task(clean_phase, self._fail_clean_exit)
		return

	def _fail_clean_exit(self, clean_phase):
		self._final_exit(clean_phase)
		self.returncode = 1
		self.wait()

	def _elog(self, elog_funcname, lines):
		out = StringIO()
		phase = self.phase
		elog_func = getattr(elog_messages, elog_funcname)
		global_havecolor = portage.output.havecolor
		try:
			portage.output.havecolor = \
				self.settings.get('NOCOLOR', 'false').lower() in ('no', 'false')
			for line in lines:
				elog_func(line, phase=phase, key=self.settings.mycpv, out=out)
		finally:
			portage.output.havecolor = global_havecolor
		msg = _unicode_decode(out.getvalue(),
			encoding=_encodings['content'], errors='replace')
		if msg:
			self.scheduler.output(msg,
				log_path=self.settings.get("PORTAGE_LOG_FILE"))
