#!/usr/bin/python -O

import sys
from copy import copy
from optparse import OptionParser, OptionValueError



import os, portage, portage_const
class WorldHandler(object):

	def name():
		return "world"
	name = staticmethod(name)

	def __init__(self):
		self.invalid = []
		self.not_installed = []
		self.okay = []
		self.found = os.access(portage_const.WORLD_FILE, os.R_OK)

		for atom in open(portage_const.WORLD_FILE).read().split():
			if not portage.isvalidatom(atom):
				self.invalid.append(atom)
			elif not portage.db["/"]["vartree"].dbapi.match(atom):
				self.not_installed.append(atom)
			else:
				self.okay.append(atom)

	def check(self):
		errors = []
		if self.found:
			errors += map(lambda x: "'%s' is not a valid atom" % x, self.invalid)
			errors += map(lambda x: "'%s' is not installed" % x, self.not_installed)
		else:
			errors.append(portage_const.WORLD_FILE + " could not be opened for reading")
		return errors

	def fix(self):
		errors = []
		try:
			open(portage_const.WORLD_FILE, "w").write("\n".join(self.okay))
		except OSError:
			errors.append(portage_const.WORLD_FILE + " could not be opened for writing")
		return errors


modules = {"world" : WorldHandler}


module_names = modules.keys()
module_names.sort()
module_names.insert(0, "all")


def exclusive(option, unused1, unused2, unused3, var=None):
	if not var:
		raise ValueError("var not specified to exclusive()")
	if getattr(parser, var, ""):
		raise OptionValueError("%s and %s are exclusive options" % (getattr(parser, var), option))
	setattr(parser, var, str(option))


usage = "usage: emaint [options] " + " | ".join(module_names)

usage+= "\n\nCurrently emaint can only check and fix problems with one's world\n"
usage+= "file.  Future versions will integrate other portage check-and-fix\n"
usage+= "tools and provide a single interface to system health checks."


parser = OptionParser(usage=usage)
parser.add_option("-c", "--check", help="check for problems",
	action="callback", callback=exclusive, callback_kwargs={"var":"action"})
parser.add_option("-f", "--fix", help="attempt to fix problems",
	action="callback", callback=exclusive, callback_kwargs={"var":"action"})
parser.action = None


(options, args) = parser.parse_args()
if len(args) != 1:
	parser.error("Incorrect number of arguments")
if args[0] not in module_names:
	parser.error("%s target is not a known target" % args[0])

if parser.action:
	action = parser.action
else:
	print "Defaulting to --check"
	action = "-c/--check"

if args[0] == "all":
	tasks = modules.values()
else:
	tasks = [modules[args[0]]]


if action == "-c/--check":
	status = "Checking %s for problems"
	func = "check"
else:
	status = "Attempting to fix %s"
	func = "fix"


for task in tasks:
	print status % task.name()
	inst = task()
	result = getattr(inst, func)()
	if result:
		print
		print "\n".join(result)
		print "\n"

print "Finished"
