#!/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
pym_path = osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), "pym")
sys.path.insert(0, pym_path)
import portage
portage._internal_caller = True
from portage import os
from portage._sets.files import StaticFileSet, WorldSelectedSet

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 = WorldSelectedSet(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)
