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

from __future__ import unicode_literals

import io

import _emerge.emergelog
from _emerge.AsynchronousTask import AsynchronousTask
from _emerge.EbuildExecuter import EbuildExecuter
from _emerge.EbuildPhase import EbuildPhase
from _emerge.EbuildBinpkg import EbuildBinpkg
from _emerge.EbuildFetcher import EbuildFetcher
from _emerge.CompositeTask import CompositeTask
from _emerge.EbuildMerge import EbuildMerge
from _emerge.EbuildFetchonly import EbuildFetchonly
from _emerge.EbuildBuildDir import EbuildBuildDir
from _emerge.MiscFunctionsProcess import MiscFunctionsProcess
from _emerge.TaskSequence import TaskSequence

import portage
from portage import _encodings, _unicode_decode, _unicode_encode, os
from portage.package.ebuild.digestcheck import digestcheck
from portage.package.ebuild.doebuild import _check_temp_dir
from portage.package.ebuild._spawn_nofetch import SpawnNofetchWithoutBuilddir

class EbuildBuild(CompositeTask):

	__slots__ = ("args_set", "config_pool", "find_blockers",
		"ldpath_mtimes", "logger", "opts", "pkg", "pkg_count",
		"prefetcher", "settings", "world_atom") + \
		("_build_dir", "_buildpkg", "_ebuild_path", "_issyspkg", "_tree")

	def _start(self):

		pkg = self.pkg
		settings = self.settings

		if not self.opts.fetchonly:
			rval = _check_temp_dir(settings)
			if rval != os.EX_OK:
				self.returncode = rval
				self._current_task = None
				self._async_wait()
				return

		root_config = pkg.root_config
		tree = "porttree"
		self._tree = tree
		portdb = root_config.trees[tree].dbapi
		settings.setcpv(pkg)
		settings.configdict["pkg"]["EMERGE_FROM"] = "ebuild"
		if self.opts.buildpkgonly:
			settings.configdict["pkg"]["MERGE_TYPE"] = "buildonly"
		else:
			settings.configdict["pkg"]["MERGE_TYPE"] = "source"
		ebuild_path = portdb.findname(pkg.cpv, myrepo=pkg.repo)
		if ebuild_path is None:
			raise AssertionError("ebuild not found for '%s'" % pkg.cpv)
		self._ebuild_path = ebuild_path
		portage.doebuild_environment(ebuild_path, 'setup',
			settings=self.settings, db=portdb)

		# Check the manifest here since with --keep-going mode it's
		# currently possible to get this far with a broken manifest.
		if not self._check_manifest():
			self.returncode = 1
			self._current_task = None
			self._async_wait()
			return

		prefetcher = self.prefetcher
		if prefetcher is None:
			pass
		elif prefetcher.isAlive() and \
			prefetcher.poll() is None:

			if not self.background:
				fetch_log = os.path.join(
					_emerge.emergelog._emerge_log_dir, 'emerge-fetch.log')
				msg = (
					'Fetching files in the background.',
					'To view fetch progress, run in another terminal:',
					'tail -f %s' % fetch_log,
				)
				out = portage.output.EOutput()
				for l in msg:
					out.einfo(l)

			self._current_task = prefetcher
			prefetcher.addExitListener(self._prefetch_exit)
			return

		self._prefetch_exit(prefetcher)

	def _check_manifest(self):
		success = True

		settings = self.settings
		if 'strict' in settings.features and \
			'digest' not in settings.features:
			settings['O'] = os.path.dirname(self._ebuild_path)
			quiet_setting = settings.get('PORTAGE_QUIET')
			settings['PORTAGE_QUIET'] = '1'
			try:
				success = digestcheck([], settings, strict=True)
			finally:
				if quiet_setting:
					settings['PORTAGE_QUIET'] = quiet_setting
				else:
					del settings['PORTAGE_QUIET']

		return success

	def _prefetch_exit(self, prefetcher):

		if self._was_cancelled():
			self.wait()
			return

		opts = self.opts
		pkg = self.pkg
		settings = self.settings

		if opts.fetchonly:
			if opts.pretend:
				fetcher = EbuildFetchonly(
					fetch_all=opts.fetch_all_uri,
					pkg=pkg, pretend=opts.pretend,
					settings=settings)
				retval = fetcher.execute()
				self.returncode = retval
				self.wait()
				return
			else:
				fetcher = EbuildFetcher(
					config_pool=self.config_pool,
					ebuild_path=self._ebuild_path,
					fetchall=self.opts.fetch_all_uri,
					fetchonly=self.opts.fetchonly,
					background=False,
					logfile=None,
					pkg=self.pkg,
					scheduler=self.scheduler)
				self._start_task(fetcher, self._fetchonly_exit)
				return

		self._build_dir = EbuildBuildDir(
			scheduler=self.scheduler, settings=settings)
		self._build_dir.lock()

		# Cleaning needs to happen before fetch, since the build dir
		# is used for log handling.
		msg = " === (%s of %s) Cleaning (%s::%s)" % \
			(self.pkg_count.curval, self.pkg_count.maxval,
			self.pkg.cpv, self._ebuild_path)
		short_msg = "emerge: (%s of %s) %s Clean" % \
			(self.pkg_count.curval, self.pkg_count.maxval, self.pkg.cpv)
		self.logger.log(msg, short_msg=short_msg)

		pre_clean_phase = EbuildPhase(background=self.background,
			phase='clean', scheduler=self.scheduler, settings=self.settings)
		self._start_task(pre_clean_phase, self._pre_clean_exit)

	def _fetchonly_exit(self, fetcher):
		self._final_exit(fetcher)
		if self.returncode != os.EX_OK:
			self.returncode = None
			portdb = self.pkg.root_config.trees[self._tree].dbapi
			self._start_task(SpawnNofetchWithoutBuilddir(
				background=self.background,
				portdb=portdb,
				ebuild_path=self._ebuild_path,
				scheduler=self.scheduler,
				settings=self.settings),
				self._nofetch_without_builddir_exit)
			return

		self.wait()

	def _nofetch_without_builddir_exit(self, nofetch):
		self._final_exit(nofetch)
		self.returncode = 1
		self.wait()

	def _pre_clean_exit(self, pre_clean_phase):
		if self._default_exit(pre_clean_phase) != os.EX_OK:
			self._unlock_builddir()
			self.wait()
			return

		# for log handling
		portage.prepare_build_dirs(self.pkg.root, self.settings, 1)

		fetcher = EbuildFetcher(config_pool=self.config_pool,
			ebuild_path=self._ebuild_path,
			fetchall=self.opts.fetch_all_uri,
			fetchonly=self.opts.fetchonly,
			background=self.background,
			logfile=self.settings.get('PORTAGE_LOG_FILE'),
			pkg=self.pkg, scheduler=self.scheduler)

		try:
			already_fetched = fetcher.already_fetched(self.settings)
		except portage.exception.InvalidDependString as e:
			msg_lines = []
			msg = "Fetch failed for '%s' due to invalid SRC_URI: %s" % \
				(self.pkg.cpv, e)
			msg_lines.append(msg)
			fetcher._eerror(msg_lines)
			portage.elog.elog_process(self.pkg.cpv, self.settings)
			self.returncode = 1
			self._current_task = None
			self._unlock_builddir()
			self.wait()
			return

		if already_fetched:
			# This case is optimized to skip the fetch queue.
			fetcher = None
			self._fetch_exit(fetcher)
			return

		# Allow the Scheduler's fetch queue to control the
		# number of concurrent fetchers.
		fetcher.addExitListener(self._fetch_exit)
		self._task_queued(fetcher)
		self.scheduler.fetch.schedule(fetcher)

	def _fetch_exit(self, fetcher):

		if fetcher is not None and \
			self._default_exit(fetcher) != os.EX_OK:
			self._fetch_failed()
			return

		# discard successful fetch log
		self._build_dir.clean_log()
		pkg = self.pkg
		logger = self.logger
		opts = self.opts
		pkg_count = self.pkg_count
		scheduler = self.scheduler
		settings = self.settings
		features = settings.features
		ebuild_path = self._ebuild_path
		system_set = pkg.root_config.sets["system"]

		#buildsyspkg: Check if we need to _force_ binary package creation
		self._issyspkg = "buildsyspkg" in features and \
				system_set.findAtomForPackage(pkg) and \
				"buildpkg" not in features and \
				opts.buildpkg != 'n'

		if ("buildpkg" in features or self._issyspkg) \
			and not self.opts.buildpkg_exclude.findAtomForPackage(pkg):

			self._buildpkg = True

			msg = " === (%s of %s) Compiling/Packaging (%s::%s)" % \
				(pkg_count.curval, pkg_count.maxval, pkg.cpv, ebuild_path)
			short_msg = "emerge: (%s of %s) %s Compile" % \
				(pkg_count.curval, pkg_count.maxval, pkg.cpv)
			logger.log(msg, short_msg=short_msg)

		else:
			msg = " === (%s of %s) Compiling/Merging (%s::%s)" % \
				(pkg_count.curval, pkg_count.maxval, pkg.cpv, ebuild_path)
			short_msg = "emerge: (%s of %s) %s Compile" % \
				(pkg_count.curval, pkg_count.maxval, pkg.cpv)
			logger.log(msg, short_msg=short_msg)

		build = EbuildExecuter(background=self.background, pkg=pkg,
			scheduler=scheduler, settings=settings)
		self._start_task(build, self._build_exit)

	def _fetch_failed(self):
		# We only call the pkg_nofetch phase if either RESTRICT=fetch
		# is set or the package has explicitly overridden the default
		# pkg_nofetch implementation. This allows specialized messages
		# to be displayed for problematic packages even though they do
		# not set RESTRICT=fetch (bug #336499).

		if 'fetch' not in self.pkg.restrict and \
			'nofetch' not in self.pkg.defined_phases:
			self._unlock_builddir()
			self.wait()
			return

		self.returncode = None
		nofetch_phase = EbuildPhase(background=self.background,
			phase='nofetch', scheduler=self.scheduler, settings=self.settings)
		self._start_task(nofetch_phase, self._nofetch_exit)

	def _nofetch_exit(self, nofetch_phase):
		self._final_exit(nofetch_phase)
		self._unlock_builddir()
		self.returncode = 1
		self.wait()

	def _unlock_builddir(self):
		portage.elog.elog_process(self.pkg.cpv, self.settings)
		self._build_dir.unlock()

	def _build_exit(self, build):
		if self._default_exit(build) != os.EX_OK:
			self._unlock_builddir()
			self.wait()
			return

		buildpkg = self._buildpkg

		if not buildpkg:
			self._final_exit(build)
			self.wait()
			return

		if self._issyspkg:
			msg = ">>> This is a system package, " + \
				"let's pack a rescue tarball.\n"
			self.scheduler.output(msg,
				log_path=self.settings.get("PORTAGE_LOG_FILE"))

		binpkg_tasks = TaskSequence()
		requested_binpkg_formats = self.settings.get("PORTAGE_BINPKG_FORMAT", "tar").split()
		for pkg_fmt in portage.const.SUPPORTED_BINPKG_FORMATS:
			if pkg_fmt in requested_binpkg_formats:
				if pkg_fmt == "rpm":
					binpkg_tasks.add(EbuildPhase(background=self.background,
						phase="rpm", scheduler=self.scheduler,
						settings=self.settings))
				else:
					task = EbuildBinpkg(
						background=self.background,
						pkg=self.pkg, scheduler=self.scheduler,
						settings=self.settings)
					binpkg_tasks.add(task)
					# Guarantee that _record_binpkg_info is called
					# immediately after EbuildBinpkg. Note that
					# task.addExitListener does not provide the
					# necessary guarantee (see bug 578204).
					binpkg_tasks.add(self._RecordBinpkgInfo(
						ebuild_binpkg=task, ebuild_build=self))

		if binpkg_tasks:
			self._start_task(binpkg_tasks, self._buildpkg_exit)
			return

		self._final_exit(build)
		self.wait()

	class _RecordBinpkgInfo(AsynchronousTask):
		"""
		This class wraps the EbuildBuild _record_binpkg_info method
		with an AsynchronousTask interface, so that it can be
		scheduled as a member of a TaskSequence.
		"""

		__slots__ = ('ebuild_binpkg', 'ebuild_build',)

		def _start(self):
			self.ebuild_build._record_binpkg_info(self.ebuild_binpkg)
			AsynchronousTask._start(self)

	def _buildpkg_exit(self, packager):
		"""
		Released build dir lock when there is a failure or
		when in buildpkgonly mode. Otherwise, the lock will
		be released when merge() is called.
		"""

		if self._default_exit(packager) != os.EX_OK:
			self._unlock_builddir()
			self.wait()
			return

		if self.opts.buildpkgonly:
			phase = 'success_hooks'
			success_hooks = MiscFunctionsProcess(
				background=self.background,
				commands=[phase], phase=phase,
				scheduler=self.scheduler, settings=self.settings)
			self._start_task(success_hooks,
				self._buildpkgonly_success_hook_exit)
			return

		# Continue holding the builddir lock until
		# after the package has been installed.
		self._current_task = None
		self.returncode = packager.returncode
		self.wait()

	def _record_binpkg_info(self, task):
		if task.returncode != os.EX_OK:
			return

		# Save info about the created binary package, so that
		# identifying information can be passed to the install
		# task, to be recorded in the installed package database.
		pkg = task.get_binpkg_info()
		infoloc = os.path.join(self.settings["PORTAGE_BUILDDIR"],
			"build-info")
		info = {
			"BINPKGMD5": "%s\n" % pkg._metadata["MD5"],
		}
		if pkg.build_id is not None:
			info["BUILD_ID"] = "%s\n" % pkg.build_id
		for k, v in info.items():
			with io.open(_unicode_encode(os.path.join(infoloc, k),
				encoding=_encodings['fs'], errors='strict'),
				mode='w', encoding=_encodings['repo.content'],
				errors='strict') as f:
				f.write(v)

	def _buildpkgonly_success_hook_exit(self, success_hooks):
		self._default_exit(success_hooks)
		self.returncode = None
		# Need to call "clean" phase for buildpkgonly mode
		portage.elog.elog_process(self.pkg.cpv, self.settings)
		phase = 'clean'
		clean_phase = EbuildPhase(background=self.background,
			phase=phase, scheduler=self.scheduler, settings=self.settings)
		self._start_task(clean_phase, self._clean_exit)

	def _clean_exit(self, clean_phase):
		if self._final_exit(clean_phase) != os.EX_OK or \
			self.opts.buildpkgonly:
			self._unlock_builddir()
		self.wait()

	def create_install_task(self):
		"""
		Install the package and then clean up and release locks.
		Only call this after the build has completed successfully
		and neither fetchonly nor buildpkgonly mode are enabled.
		"""

		ldpath_mtimes = self.ldpath_mtimes
		logger = self.logger
		pkg = self.pkg
		pkg_count = self.pkg_count
		settings = self.settings
		world_atom = self.world_atom
		ebuild_path = self._ebuild_path
		tree = self._tree

		task = EbuildMerge(exit_hook=self._install_exit,
			find_blockers=self.find_blockers,
			ldpath_mtimes=ldpath_mtimes, logger=logger, pkg=pkg,
			pkg_count=pkg_count, pkg_path=ebuild_path,
			scheduler=self.scheduler,
			settings=settings, tree=tree, world_atom=world_atom)

		msg = " === (%s of %s) Merging (%s::%s)" % \
			(pkg_count.curval, pkg_count.maxval,
			pkg.cpv, ebuild_path)
		short_msg = "emerge: (%s of %s) %s Merge" % \
			(pkg_count.curval, pkg_count.maxval, pkg.cpv)
		logger.log(msg, short_msg=short_msg)

		return task

	def _install_exit(self, task):
		self._unlock_builddir()
