#!/usr/bin/python -O
# Copyright 1999-2012 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2

from __future__ import print_function

import platform
import signal
import sys
# This block ensures that ^C interrupts are handled quietly.
try:

	def exithandler(signum,frame):
		signal.signal(signal.SIGINT, signal.SIG_IGN)
		signal.signal(signal.SIGTERM, signal.SIG_IGN)
		sys.exit(128 + signum)

	signal.signal(signal.SIGINT, exithandler)
	signal.signal(signal.SIGTERM, exithandler)
	# Prevent "[Errno 32] Broken pipe" exceptions when
	# writing to a pipe.
	signal.signal(signal.SIGPIPE, signal.SIG_DFL)

except KeyboardInterrupt:
	sys.exit(128 + signal.SIGINT)

def debug_signal(signum, frame):
	import pdb
	pdb.set_trace()

if platform.python_implementation() == 'Jython':
	debug_signum = signal.SIGUSR2 # bug #424259
else:
	debug_signum = signal.SIGUSR1

signal.signal(debug_signum, debug_signal)

import imp
import io
import optparse
import os

description = "See the ebuild(1) man page for more info"
usage = "Usage: ebuild <ebuild file> <command> [command] ..."
parser = optparse.OptionParser(description=description, usage=usage)

force_help = "When used together with the digest or manifest " + \
	"command, this option forces regeneration of digests for all " + \
	"distfiles associated with the current ebuild. Any distfiles " + \
	"that do not already exist in ${DISTDIR} will be automatically fetched."

parser.add_option("--force", help=force_help, action="store_true", dest="force")
parser.add_option("--color", help="enable or disable color output",
	type="choice", choices=("y", "n"))
parser.add_option("--debug", help="show debug output",
	action="store_true", dest="debug")
parser.add_option("--version", help="show version and exit",
	action="store_true", dest="version")
parser.add_option("--ignore-default-opts",
	action="store_true",
	help="do not use the EBUILD_DEFAULT_OPTS environment variable")
parser.add_option("--skip-manifest", help="skip all manifest checks",
	action="store_true", dest="skip_manifest")

opts, pargs = parser.parse_args(args=sys.argv[1:])

from os import path as osp
pym_path = osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), "pym")
sys.path.insert(0, pym_path)
import portage
portage._internal_warnings = True
from portage import os
from portage import _encodings
from portage import _shell_quote
from portage import _unicode_decode
from portage import _unicode_encode
from portage.const import VDB_PATH
from _emerge.Package import Package
from _emerge.RootConfig import RootConfig

if opts.version:
	print("Portage", portage.VERSION)
	sys.exit(os.EX_OK)

if len(pargs) < 2:
	parser.error("missing required args")

if not opts.ignore_default_opts:
	default_opts = portage.settings.get("EBUILD_DEFAULT_OPTS", "").split()
	opts, pargs = parser.parse_args(default_opts + sys.argv[1:])

debug = opts.debug
force = opts.force

import portage.util, portage.const

# do this _after_ 'import portage' to prevent unnecessary tracing
if debug and "python-trace" in portage.features:
	import portage.debug
	portage.debug.set_trace(True)

if not opts.color == 'y' and \
	(opts.color == 'n' or \
	portage.settings.get('NOCOLOR') in ('yes', 'true') or \
	portage.settings.get('TERM') == 'dumb' or \
	not sys.stdout.isatty()):
	portage.output.nocolor()
	portage.settings.unlock()
	portage.settings['NOCOLOR'] = 'true'
	portage.settings.lock()

ebuild = pargs.pop(0)

pf = None
if ebuild.endswith(".ebuild"):
	pf = os.path.basename(ebuild)[:-7]

if pf is None:
	portage.writemsg("'%s' does not end with '.ebuild'.\n" % \
		(ebuild,), noiselevel=-1)
	sys.exit(1)

if not os.path.isabs(ebuild):
	mycwd = os.getcwd()
	# Try to get the non-canonical path from the PWD evironment variable, since
	# the canonical path returned from os.getcwd() may may be unusable in
	# cases where the directory stucture is built from symlinks.
	pwd = os.environ.get('PWD', '')
	if sys.hexversion < 0x3000000:
		pwd = _unicode_decode(pwd, encoding=_encodings['content'],
			errors='strict')
	if pwd and pwd != mycwd and \
		os.path.realpath(pwd) == mycwd:
		mycwd = portage.normalize_path(pwd)
	ebuild = os.path.join(mycwd, ebuild)
ebuild = portage.normalize_path(ebuild)
# portdbapi uses the canonical path for the base of the portage tree, but
# subdirectories of the base can be built from symlinks (like crossdev does).
ebuild_portdir = os.path.realpath(
	os.path.dirname(os.path.dirname(os.path.dirname(ebuild))))
ebuild = os.path.join(ebuild_portdir, *ebuild.split(os.path.sep)[-3:])
vdb_path = os.path.realpath(os.path.join(portage.settings['EROOT'], VDB_PATH))

# Make sure that portdb.findname() returns the correct ebuild.
if ebuild_portdir != vdb_path and \
	ebuild_portdir not in portage.portdb.porttrees:
	portdir_overlay = portage.settings.get("PORTDIR_OVERLAY", "")
	if sys.hexversion >= 0x3000000:
		os.environ["PORTDIR_OVERLAY"] = \
			portdir_overlay + \
			" " + _shell_quote(ebuild_portdir)
	else:
		os.environ["PORTDIR_OVERLAY"] = \
			_unicode_encode(portdir_overlay,
			encoding=_encodings['content'], errors='strict') + \
			" " + _unicode_encode(_shell_quote(ebuild_portdir),
			encoding=_encodings['content'], errors='strict')

	print("Appending %s to PORTDIR_OVERLAY..." % ebuild_portdir)
	imp.reload(portage)

myrepo = None
if ebuild_portdir != vdb_path:
	myrepo = portage.portdb.getRepositoryName(ebuild_portdir)

if not os.path.exists(ebuild):
	print("'%s' does not exist." % ebuild)
	sys.exit(1)

ebuild_split = ebuild.split("/")
cpv = "%s/%s" % (ebuild_split[-3], pf)

with io.open(_unicode_encode(ebuild, encoding=_encodings['fs'], errors='strict'),
	mode='r', encoding=_encodings['repo.content'], errors='replace') as f:
	eapi = portage._parse_eapi_ebuild_head(f)[0]
if eapi is None:
	eapi = "0"
if not portage.catpkgsplit(cpv, eapi=eapi):
	print("!!! %s does not follow correct package syntax." % (cpv))
	sys.exit(1)

if ebuild.startswith(vdb_path):
	mytree = "vartree"
	pkg_type = "installed"

	portage_ebuild = portage.db[portage.root][mytree].dbapi.findname(cpv, myrepo=myrepo)

	if os.path.realpath(portage_ebuild) != ebuild:
		print("!!! Portage seems to think that %s is at %s" % (cpv, portage_ebuild))
		sys.exit(1)

else:
	mytree = "porttree"
	pkg_type = "ebuild"

	portage_ebuild = portage.portdb.findname(cpv, myrepo=myrepo)

	if not portage_ebuild or portage_ebuild != ebuild:
		print("!!! %s does not seem to have a valid PORTDIR structure." % ebuild)
		sys.exit(1)

if len(pargs) > 1 and "config" in pargs:
	print("config must be called on it's own, not combined with any other phase")
	sys.exit(1)

def discard_digests(myebuild, mysettings, mydbapi):
	"""Discard all distfiles digests for the given ebuild.  This is useful when
	upstream has changed the identity of the distfiles and the user would
	otherwise have to manually remove the Manifest and files/digest-* files in
	order to ensure correct results."""
	try:
		portage._doebuild_manifest_exempt_depend += 1
		pkgdir = os.path.dirname(myebuild)
		fetchlist_dict = portage.FetchlistDict(pkgdir, mysettings, mydbapi)
		mf = mysettings.repositories.get_repo_for_location(
			os.path.dirname(os.path.dirname(pkgdir)))
		mf = mf.load_manifest(pkgdir, mysettings["DISTDIR"],
			fetchlist_dict=fetchlist_dict)
		mf.create(requiredDistfiles=None,
			assumeDistHashesSometimes=True, assumeDistHashesAlways=True)
		distfiles = fetchlist_dict[cpv]
		for myfile in distfiles:
			try:
				del mf.fhashdict["DIST"][myfile]
			except KeyError:
				pass
		mf.write()
	finally:
		portage._doebuild_manifest_exempt_depend -= 1

portage.settings.validate() # generate warning messages if necessary

build_dir_phases = set(["setup", "unpack", "prepare", "configure", "compile",
	"test", "install", "package", "rpm", "merge", "qmerge"])

# If the current metadata is invalid then force the ebuild to be
# sourced again even if $T/environment already exists.
ebuild_changed = False
if mytree == "porttree" and build_dir_phases.intersection(pargs):
	ebuild_changed = \
		portage.portdb._pull_valid_cache(cpv, ebuild, ebuild_portdir)[0] is None

tmpsettings = portage.config(clone=portage.settings)
tmpsettings["PORTAGE_VERBOSE"] = "1"
tmpsettings.backup_changes("PORTAGE_VERBOSE")

if opts.skip_manifest:
	tmpsettings["EBUILD_SKIP_MANIFEST"] = "1"
	tmpsettings.backup_changes("EBUILD_SKIP_MANIFEST")

if opts.skip_manifest or \
	"digest" in tmpsettings.features or \
	"digest" in pargs or \
	"manifest" in pargs:
	portage._doebuild_manifest_exempt_depend += 1

if "test" in pargs:
	# This variable is a signal to config.regenerate() to
	# indicate that the test phase should be enabled regardless
	# of problems such as masked "test" USE flag.
	tmpsettings["EBUILD_FORCE_TEST"] = "1"
	tmpsettings.backup_changes("EBUILD_FORCE_TEST")
	tmpsettings.features.add("test")

tmpsettings.features.discard("fail-clean")

if "merge" in pargs and "noauto" in tmpsettings.features:
	print("Disabling noauto in features... merge disables it. (qmerge doesn't)")
	tmpsettings.features.discard("noauto")

try:
	metadata = dict(zip(Package.metadata_keys,
		portage.db[portage.settings['EROOT']][mytree].dbapi.aux_get(
		cpv, Package.metadata_keys, myrepo=myrepo)))
except KeyError:
	# aux_get failure, message should have been shown on stderr.
	sys.exit(1)

root_config = RootConfig(portage.settings,
	portage.db[portage.settings['EROOT']], None)

pkg = Package(built=(pkg_type != "ebuild"), cpv=cpv,
	installed=(pkg_type=="installed"),
	metadata=metadata, root_config=root_config,
	type_name=pkg_type)

# Apply package.env and repo-level settings. This allows per-package
# FEATURES and other variables (possibly PORTAGE_TMPDIR) to be
# available as soon as possible. Also, note that the only way to ensure
# that setcpv gets metadata from the correct repository is to pass in
# a Package instance, as we do here (previously we had to modify
# portdb.porttrees in order to accomplish this).
tmpsettings.setcpv(pkg)

def stale_env_warning():
	if "clean" not in pargs and \
		"noauto" not in tmpsettings.features and \
		build_dir_phases.intersection(pargs):
		portage.doebuild_environment(ebuild, "setup", portage.root,
			tmpsettings, debug, 1, portage.portdb)
		env_filename = os.path.join(tmpsettings["T"], "environment")
		if os.path.exists(env_filename):
			msg = ("Existing ${T}/environment for '%s' will be sourced. " + \
				"Run 'clean' to start with a fresh environment.") % \
				(tmpsettings["PF"], )
			from textwrap import wrap
			msg = wrap(msg, 70)
			for x in msg:
				portage.writemsg(">>> %s\n" % x)

			if ebuild_changed:
				open(os.path.join(tmpsettings['PORTAGE_BUILDDIR'],
					'.ebuild_changed'), 'w')

from portage.exception import PermissionDenied, \
	PortagePackageException, UnsupportedAPIException

if 'digest' in tmpsettings.features and \
	not set(["digest", "manifest"]).intersection(pargs):
	pargs = ['digest'] + pargs

checked_for_stale_env = False

for arg in pargs:
	try:
		if not checked_for_stale_env and arg not in ("digest","manifest"):
			# This has to go after manifest generation since otherwise
			# aux_get() might fail due to invalid ebuild digests.
			stale_env_warning()
			checked_for_stale_env = True

		if arg in ("digest", "manifest") and force:
			discard_digests(ebuild, tmpsettings, portage.portdb)
		a = portage.doebuild(ebuild, arg, portage.root, tmpsettings,
			debug=debug, tree=mytree,
			vartree=portage.db[portage.root]['vartree'])
	except KeyboardInterrupt:
		print("Interrupted.")
		a = 1
	except KeyError:
		# aux_get error
		a = 1
	except UnsupportedAPIException as e:
		from textwrap import wrap
		msg = wrap(str(e), 70)
		del e
		for x in msg:
			portage.writemsg("!!! %s\n" % x, noiselevel=-1)
		a = 1
	except PortagePackageException as e:
		portage.writemsg("!!! %s\n" % (e,), noiselevel=-1)
		a = 1
	except PermissionDenied as e:
		portage.writemsg("!!! Permission Denied: %s\n" % (e,), noiselevel=-1)
		a = 1
	if a == None:
		print("Could not run the required binary?")
		a = 127
	if a:
		sys.exit(a)
