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

from __future__ import print_function

import sys
from os import path as osp
if osp.isfile(osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), ".portage_not_installed")):
	sys.path.insert(0, osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), "lib"))
import portage
portage._internal_caller = True
from portage import os
from portage._sets.files import StaticFileSet, WorldSelectedPackagesSet

import re
import tempfile
import textwrap

__candidatematcher__ = re.compile("^[0-9]+: \\*\\*\\* emerge ")
__noncandidatematcher__ = re.compile(" sync( |$)| clean( |$)| search( |$)|--oneshot|--fetchonly| unmerge( |$)")

def issyspkg(pkgline):
	return (pkgline[0] == "*")

def iscandidate(logline):
	return (__candidatematcher__.match(logline) \
				and not __noncandidatematcher__.search(logline))

def getpkginfo(logline):
	logline = re.sub("^[0-9]+: \\*\\*\\* emerge ", "", logline)
	logline = logline.strip()
	logline = re.sub("(\\S+\\.(ebuild|tbz2))|(--\\S+)|inject ", "", logline)
	return logline.strip()

__uniqlist__ = []
def isunwanted(pkgline):
	if pkgline in ["world", "system", "depclean", "info", "regen", ""]:
		return False
	elif pkgline in __uniqlist__:
		return False
	elif not re.search("^[a-zA-Z<>=~]", pkgline):
		return False
	else:
		__uniqlist__.append(pkgline)
		return True

eroot = portage.settings['EROOT']
world_file = os.path.join(eroot, portage.WORLD_FILE)

# show a little description if we have arguments
if len(sys.argv) >= 2 and sys.argv[1] in ["-h", "--help"]:
	print("This script regenerates the portage world file by checking the portage")
	print("logfile for all actions that you've done in the past. It ignores any")
	print("arguments except --help. It is recommended that you make a backup of")
	print("your existing world file (%s) before using this tool." % world_file)
	sys.exit(0)

worldlist = portage.grabfile(world_file)
syslist = [x for x in portage.settings.packages if issyspkg(x)]

logfile = portage.grabfile(os.path.join(eroot, "var/log/emerge.log"))
biglist = [getpkginfo(x) for x in logfile if iscandidate(x)]
tmplist = []
for l in biglist:
	tmplist += l.split()
biglist = [x for x in tmplist if isunwanted(x)]
#for p in biglist:
#	print(p)
#sys.exit(0)

# resolving virtuals
realsyslist = []
for mykey in syslist:
	# drop the asterix
	mykey = mykey[1:]
	#print("candidate:",mykey)
	mylist = portage.db[eroot]["vartree"].dbapi.match(mykey)
	if mylist:
		mykey=portage.cpv_getkey(mylist[0])
		if mykey not in realsyslist:
			realsyslist.append(mykey)

for mykey in biglist:
	#print("checking:",mykey)
	try:
		mylist = portage.db[eroot]["vartree"].dbapi.match(mykey)
	except (portage.exception.InvalidAtom, KeyError):
		if "--debug" in sys.argv:
			print("* ignoring broken log entry for %s (likely injected)" % mykey)
	except ValueError as e:
		try:
			print("* %s is an ambiguous package name, candidates are:\n%s" % (mykey, e))
		except AttributeError:
			# FIXME: Find out what causes this (bug #344845).
			print("* %s is an ambiguous package name" % (mykey,))
		continue
	if mylist:
		#print "mylist:",mylist
		myfavkey=portage.cpv_getkey(mylist[0])
		if (myfavkey not in realsyslist) and (myfavkey not in worldlist):
			print("add to world:",myfavkey)
			worldlist.append(myfavkey)

if not worldlist:
	pass
else:
	existing_set = WorldSelectedPackagesSet(eroot)
	existing_set.load()

	if not existing_set:
		existing_set.replace(worldlist)
	else:
		old_world = existing_set._filename
		fd, tmp_filename = tempfile.mkstemp(suffix=".tmp",
			prefix=os.path.basename(old_world) + ".",
			dir=os.path.dirname(old_world))
		os.close(fd)

		new_set = StaticFileSet(tmp_filename)
		new_set.update(worldlist)

		if existing_set.getAtoms() == new_set.getAtoms():
			os.unlink(tmp_filename)
		else:
			new_set.write()

			msg = "Please review differences between old and new files, " + \
				"and replace the old file if desired."

			portage.util.writemsg_stdout("\n",
				noiselevel=-1)
			for line in textwrap.wrap(msg, 65):
				portage.util.writemsg_stdout("%s\n" % line,
					noiselevel=-1)
			portage.util.writemsg_stdout("\n",
				noiselevel=-1)
			portage.util.writemsg_stdout("  old: %s\n\n" % old_world,
				noiselevel=-1)
			portage.util.writemsg_stdout("  new: %s\n\n" % tmp_filename,
				noiselevel=-1)
