# Copyright 2007-2010 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2

import time

from portage import os
from portage.versions import catpkgsplit, catsplit, pkgcmp, best
from portage.dep import Atom
from portage.localization import _
from portage.sets.base import PackageSet
from portage.sets import SetConfigError, get_boolean
import portage

__all__ = ["CategorySet", "DowngradeSet",
	"EverythingSet", "OwnerSet", "VariableSet"]

class EverythingSet(PackageSet):
	_operations = ["merge"]
	description = "Package set which contains SLOT " + \
		"atoms to match all installed packages"
	_filter = None

	def __init__(self, vdbapi, **kwargs):
		super(EverythingSet, self).__init__()
		self._db = vdbapi

	def load(self):
		myatoms = []
		db_keys = ["SLOT"]
		aux_get = self._db.aux_get
		cp_list = self._db.cp_list

		for cp in self._db.cp_all():
			cpv_list = cp_list(cp)

			if len(cpv_list) > 1:
				for cpv in cpv_list:
					slot, = aux_get(cpv, db_keys)
					atom = Atom("%s:%s" % (cp, slot))
					if self._filter:
						if self._filter(atom):
							myatoms.append(atom)
					else:
						myatoms.append(atom)

			else:
				atom = Atom(cp)
				if self._filter:
					if self._filter(atom):
						myatoms.append(atom)
				else:
					myatoms.append(atom)

		self._setAtoms(myatoms)
	
	def singleBuilder(self, options, settings, trees):
		return EverythingSet(trees["vartree"].dbapi)
	singleBuilder = classmethod(singleBuilder)

class OwnerSet(PackageSet):

	_operations = ["merge", "unmerge"]

	description = "Package set which contains all packages " + \
		"that own one or more files."

	def __init__(self, vardb=None, files=None):
		super(OwnerSet, self).__init__()
		self._db = vardb
		self._files = files

	def mapPathsToAtoms(self, paths):
		rValue = set()
		vardb = self._db
		aux_get = vardb.aux_get
		aux_keys = ["SLOT"]
		for link, p in vardb._owners.iter_owners(paths):
			cat, pn = catpkgsplit(link.mycpv)[:2]
			slot, = aux_get(link.mycpv, aux_keys)
			rValue.add("%s/%s:%s" % (cat, pn, slot))
		return rValue

	def load(self):
		self._setAtoms(self.mapPathsToAtoms(self._files))

	def singleBuilder(cls, options, settings, trees):
		if not "files" in options:
			raise SetConfigError(_("no files given"))

		return cls(vardb=trees["vartree"].dbapi,
			files=frozenset(portage.util.shlex_split(options["files"])))

	singleBuilder = classmethod(singleBuilder)

class VariableSet(EverythingSet):

	_operations = ["merge", "unmerge"]

	description = "Package set which contains all packages " + \
		"that match specified values of a specified variable."

	def __init__(self, vardb, metadatadb=None, variable=None, includes=None, excludes=None):
		super(VariableSet, self).__init__(vardb)
		self._metadatadb = metadatadb
		self._variable = variable
		self._includes = includes
		self._excludes = excludes

	def _filter(self, atom):
		ebuild = best(self._metadatadb.match(atom))
		if not ebuild:
			return False
		values, = self._metadatadb.aux_get(ebuild, [self._variable])
		values = values.split()
		if self._includes and not self._includes.intersection(values):
			return False
		if self._excludes and self._excludes.intersection(values):
			return False
		return True

	def singleBuilder(cls, options, settings, trees):

		variable = options.get("variable")
		if variable is None:
			raise SetConfigError(_("missing required attribute: 'variable'"))

		includes = options.get("includes", "")
		excludes = options.get("excludes", "")

		if not (includes or excludes):
			raise SetConfigError(_("no includes or excludes given"))
		
		metadatadb = options.get("metadata-source", "vartree")
		if not metadatadb in trees:
			raise SetConfigError(_("invalid value '%s' for option metadata-source") % metadatadb)

		return cls(trees["vartree"].dbapi,
			metadatadb=trees[metadatadb].dbapi,
			excludes=frozenset(excludes.split()),
			includes=frozenset(includes.split()),
			variable=variable)

	singleBuilder = classmethod(singleBuilder)

class DowngradeSet(PackageSet):

	_operations = ["merge", "unmerge"]

	description = "Package set which contains all packages " + \
		"for which the highest visible ebuild version is lower than " + \
		"the currently installed version."

	def __init__(self, portdb=None, vardb=None):
		super(DowngradeSet, self).__init__()
		self._portdb = portdb
		self._vardb = vardb

	def load(self):
		atoms = []
		xmatch = self._portdb.xmatch
		xmatch_level = "bestmatch-visible"
		cp_list = self._vardb.cp_list
		aux_get = self._vardb.aux_get
		aux_keys = ["SLOT"]
		for cp in self._vardb.cp_all():
			for cpv in cp_list(cp):
				slot, = aux_get(cpv, aux_keys)
				slot_atom = "%s:%s" % (cp, slot)
				ebuild = xmatch(xmatch_level, slot_atom)
				if not ebuild:
					continue
				ebuild_split = catpkgsplit(ebuild)[1:]
				installed_split = catpkgsplit(cpv)[1:]
				if pkgcmp(installed_split, ebuild_split) > 0:
					atoms.append(slot_atom)

		self._setAtoms(atoms)

	def singleBuilder(cls, options, settings, trees):
		return cls(portdb=trees["porttree"].dbapi,
			vardb=trees["vartree"].dbapi)

	singleBuilder = classmethod(singleBuilder)

class UnavailableSet(EverythingSet):

	_operations = ["unmerge"]

	description = "Package set which contains all installed " + \
		"packages for which there are no visible ebuilds " + \
		"corresponding to the same $CATEGORY/$PN:$SLOT."

	def __init__(self, vardb, metadatadb=None):
		super(UnavailableSet, self).__init__(vardb)
		self._metadatadb = metadatadb

	def _filter(self, atom):
		return not self._metadatadb.match(atom)

	def singleBuilder(cls, options, settings, trees):

		metadatadb = options.get("metadata-source", "porttree")
		if not metadatadb in trees:
			raise SetConfigError(_("invalid value '%s' for option "
				"metadata-source") % (metadatadb,))

		return cls(trees["vartree"].dbapi,
			metadatadb=trees[metadatadb].dbapi)

	singleBuilder = classmethod(singleBuilder)

class CategorySet(PackageSet):
	_operations = ["merge", "unmerge"]
	
	def __init__(self, category, dbapi, only_visible=True):
		super(CategorySet, self).__init__()
		self._db = dbapi
		self._category = category
		self._check = only_visible
		if only_visible:
			s="visible"
		else:
			s="all"
		self.description = "Package set containing %s packages of category %s" % (s, self._category)
			
	def load(self):
		myatoms = []
		for cp in self._db.cp_all():
			if catsplit(cp)[0] == self._category:
				if (not self._check) or len(self._db.match(cp)) > 0:
					myatoms.append(cp)
		self._setAtoms(myatoms)
	
	def _builderGetRepository(cls, options, repositories):
		repository = options.get("repository", "porttree")
		if not repository in repositories:
			raise SetConfigError(_("invalid repository class '%s'") % repository)
		return repository
	_builderGetRepository = classmethod(_builderGetRepository)

	def _builderGetVisible(cls, options):
		return get_boolean(options, "only_visible", True)
	_builderGetVisible = classmethod(_builderGetVisible)
		
	def singleBuilder(cls, options, settings, trees):
		if not "category" in options:
			raise SetConfigError(_("no category given"))

		category = options["category"]
		if not category in settings.categories:
			raise SetConfigError(_("invalid category name '%s'") % category)

		repository = cls._builderGetRepository(options, trees.keys())
		visible = cls._builderGetVisible(options)
		
		return CategorySet(category, dbapi=trees[repository].dbapi, only_visible=visible)
	singleBuilder = classmethod(singleBuilder)

	def multiBuilder(cls, options, settings, trees):
		rValue = {}
	
		if "categories" in options:
			categories = options["categories"].split()
			invalid = set(categories).difference(settings.categories)
			if invalid:
				raise SetConfigError(_("invalid categories: %s") % ", ".join(list(invalid)))
		else:
			categories = settings.categories
	
		repository = cls._builderGetRepository(options, trees.keys())
		visible = cls._builderGetVisible(options)
		name_pattern = options.get("name_pattern", "$category/*")
	
		if not "$category" in name_pattern and not "${category}" in name_pattern:
			raise SetConfigError(_("name_pattern doesn't include $category placeholder"))
	
		for cat in categories:
			myset = CategorySet(cat, trees[repository].dbapi, only_visible=visible)
			myname = name_pattern.replace("$category", cat)
			myname = myname.replace("${category}", cat)
			rValue[myname] = myset
		return rValue
	multiBuilder = classmethod(multiBuilder)

class AgeSet(EverythingSet):
	_operations = ["merge", "unmerge"]

	def __init__(self, vardb, mode="older", age=7):
		super(AgeSet, self).__init__(vardb)
		self._mode = mode
		self._age = age

	def _filter(self, atom):
	
		cpv = self._db.match(atom)[0]
		path = self._db.getpath(cpv, filename="COUNTER")
		age = (time.time() - os.stat(path).st_mtime) / (3600 * 24)
		if ((self._mode == "older" and age <= self._age) \
			or (self._mode == "newer" and age >= self._age)):
			return False
		else:
			return True
	
	def singleBuilder(cls, options, settings, trees):
		mode = options.get("mode", "older")
		if str(mode).lower() not in ["newer", "older"]:
			raise SetConfigError(_("invalid 'mode' value %s (use either 'newer' or 'older')") % mode)
		try:
			age = int(options.get("age", "7"))
		except ValueError as e:
			raise SetConfigError(_("value of option 'age' is not an integer"))
		return AgeSet(vardb=trees["vartree"].dbapi, mode=mode, age=age)

	singleBuilder = classmethod(singleBuilder)

class RebuiltBinaries(EverythingSet):
	_operations = ('merge',)
	_aux_keys = ('BUILD_TIME',)

	def __init__(self, vardb, bindb=None):
		super(RebuiltBinaries, self).__init__(vardb, bindb=bindb)
		self._bindb = bindb

	def _filter(self, atom):
		cpv = self._db.match(atom)[0]
		inst_build_time, = self._db.aux_get(cpv, self._aux_keys)
		try:
			bin_build_time, = self._bindb.aux_get(cpv, self._aux_keys)
		except KeyError:
			return False
		return bool(bin_build_time and (inst_build_time != bin_build_time))

	def singleBuilder(cls, options, settings, trees):
		return RebuiltBinaries(trees["vartree"].dbapi,
			bindb=trees["bintree"].dbapi)

	singleBuilder = classmethod(singleBuilder)
