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

import errno, signal, sys, os

def quickpkg_main(options, args, eout):
	from portage import catsplit, dep_expand, flatten, isvalidatom, xpak
	from portage.dep import use_reduce, paren_reduce
	from portage.util import ConfigProtect, ensure_dirs
	from portage.exception import InvalidData, InvalidDependString
	from portage.dbapi.vartree import dblink, tar_contents
	from portage.checksum import perform_md5
	import tarfile
	import portage
	root = portage.settings["ROOT"]
	trees = portage.db[root]
	vartree = trees["vartree"]
	vardb = vartree.dbapi
	bintree = trees["bintree"]
	try:
		ensure_dirs(bintree.pkgdir)
	except portage.exception.PortageException:
		pass
	if not os.access(bintree.pkgdir, os.W_OK):
		eout.eerror("No write access to '%s'" % bintree.pkgdir)
		return errno.EACCES
	successes = []
	missing = []
	config_files_excluded = 0
	include_config = options.include_config == "y"
	include_unmodified_config = options.include_unmodified_config == "y"
	for arg in args:
		try:
			atom = dep_expand(arg, mydb=vardb, settings=vartree.settings)
		except ValueError, e:
			# Multiple matches thrown from cpv_expand
			eout.eerror("Please use a more specific atom: %s" % \
				" ".join(e.args[0]))
			del e
			missing.append(arg)
			continue
		except InvalidData, e:
			eout.eerror("Invalid atom: %s" % str(e))
			del e
			missing.append(arg)
			continue
		if not isvalidatom(atom):
			eout.eerror("Invalid atom: %s" % atom)
			missing.append(arg)
			continue
		matches = vardb.match(atom)
		pkgs_for_arg = 0
		for cpv in matches:
			excluded_config_files = []
			bintree.prevent_collision(cpv)
			cat, pkg = catsplit(cpv)
			dblnk = dblink(cat, pkg, root,
				vartree.settings, treetype="vartree",
				vartree=vartree)
			dblnk.lockdb()
			try:
				if not dblnk.exists():
					# unmerged by a concurrent process
					continue
				iuse, use, restrict = vardb.aux_get(cpv,
					["IUSE","USE","RESTRICT"])
				iuse = [ x.lstrip("+-") for x in iuse.split() ]
				use = use.split()
				try:
					restrict = flatten(use_reduce(
						paren_reduce(restrict), uselist=use))
				except InvalidDependString, e:
					eout.eerror("Invalid RESTRICT metadata " + \
						"for '%s': %s; skipping" % (cpv, str(e)))
					del e
					continue
				if "bindist" in iuse and "bindist" not in use:
					eout.ewarn("%s: package was emerged with USE=-bindist!" % cpv)
					eout.ewarn("%s: it may not be legal to redistribute this." % cpv)
				elif "bindist" in restrict:
					eout.ewarn("%s: package has RESTRICT=bindist!" % cpv)
					eout.ewarn("%s: it may not be legal to redistribute this." % cpv)
				eout.ebegin("Building package for %s" % cpv)
				pkgs_for_arg += 1
				contents = dblnk.getcontents()
				protect = None
				if not include_config:
					confprot = ConfigProtect(root,
						portage.settings.get("CONFIG_PROTECT","").split(),
						portage.settings.get("CONFIG_PROTECT_MASK","").split())
					def protect(filename):
						if not confprot.isprotected(filename):
							return False
						if include_unmodified_config:
							file_data = contents[filename]
							if file_data[0] == "obj":
								orig_md5 = file_data[2].lower()
								cur_md5 = perform_md5(filename, calc_prelink=1)
								if orig_md5 == cur_md5:
									return False
						excluded_config_files.append(filename)
						return True
				xpdata = xpak.xpak(dblnk.dbdir)
				binpkg_tmpfile = os.path.join(bintree.pkgdir,
					cpv + ".tbz2." + str(os.getpid()))
				ensure_dirs(os.path.dirname(binpkg_tmpfile))
				tar = tarfile.open(binpkg_tmpfile, "w:bz2")
				tar_contents(contents, root, tar, protect=protect)
				tar.close()
				xpak.tbz2(binpkg_tmpfile).recompose_mem(xpdata)
			finally:
				dblnk.unlockdb()
			bintree.inject(cpv, filename=binpkg_tmpfile)
			binpkg_path = bintree.getname(cpv)
			try:
				s = os.stat(binpkg_path)
			except OSError, e:
				# Sanity check, shouldn't happen normally.
				eout.eend(1)
				eout.eerror(str(e))
				del e
				eout.eerror("Failed to create package: '%s'" % binpkg_path)
			else:
				eout.eend(0)
				successes.append((cpv, s.st_size))
				config_files_excluded += len(excluded_config_files)
				for filename in excluded_config_files:
					eout.ewarn("Excluded config: '%s'" % filename)
		if not pkgs_for_arg:
			eout.eerror("Could not find anything " + \
				"to match '%s'; skipping" % arg)
			missing.append(arg)
	if not successes:
		eout.eerror("No packages found")
		return 1
	print
	eout.einfo("Packages now in '%s':" % bintree.pkgdir)
	import math
	units = {10:'K', 20:'M', 30:'G', 40:'T',
		50:'P', 60:'E', 70:'Z', 80:'Y'}
	for cpv, size in successes:
		if not size:
			# avoid OverflowError in math.log()
			size_str = "0"
		else:
			power_of_2 = math.log(size, 2)
			power_of_2 = 10*int(power_of_2/10)
			unit = units.get(power_of_2)
			if unit:
				size = float(size)/(2**power_of_2)
				size_str = "%.1f" % size
				if len(size_str) > 4:
					# emulate `du -h`, don't show too many sig figs
					size_str = str(int(size))
				size_str += unit
			else:
				size_str = str(size)
		eout.einfo("%s: %s" % (cpv, size_str))
	if config_files_excluded:
		print
		eout.ewarn("Excluded config files: %d" % config_files_excluded)
		eout.ewarn("See --help if you would like to include config files.")
	if missing:
		print
		eout.ewarn("The following packages could not be found:")
		eout.ewarn(" ".join(missing))
		return 2
	return os.EX_OK

if __name__ == "__main__":
	usage = "quickpkg [options] <list of package atoms>"
	from optparse import OptionParser
	parser = OptionParser(usage=usage)
	parser.add_option("--umask",
		default="0077",
		help="umask used during package creation (default is 0077)")
	parser.add_option("--ignore-default-opts",
		action="store_true",
		help="do not use the QUICKPKG_DEFAULT_OPTS environment variable")
	parser.add_option("--include-config",
		type="choice",
		choices=["y","n"],
		default="n",
		metavar="<y|n>",
		help="include all files protected by CONFIG_PROTECT (as a security precaution, default is 'n')")
	parser.add_option("--include-unmodified-config",
		type="choice",
		choices=["y","n"],
		default="n",
		metavar="<y|n>",
		help="include files protected by CONFIG_PROTECT that have not been modified since installation (as a security precaution, default is 'n')")
	options, args = parser.parse_args(sys.argv[1:])
	if not options.ignore_default_opts:
		from portage import settings
		default_opts = settings.get("QUICKPKG_DEFAULT_OPTS","").split()
		options, args = parser.parse_args(default_opts + sys.argv[1:])
	if not args:
		parser.error("no packages atoms given")
	try:
		umask = int(options.umask, 8)
	except ValueError:
		parser.error("invalid umask: %s" % options.umask)
	# We need to ensure a sane umask for the packages that will be created.
	old_umask = os.umask(umask)
	from portage.output import get_term_size, EOutput
	eout = EOutput()
	def sigwinch_handler(signum, frame):
		lines, eout.term_columns = get_term_size()
	signal.signal(signal.SIGWINCH, sigwinch_handler)
	try:
		retval = quickpkg_main(options, args, eout)
	finally:
		os.umask(old_umask)
		signal.signal(signal.SIGWINCH, signal.SIG_DFL)
	sys.exit(retval)
