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

import time

from portage import os
from portage.versions import best, catsplit, vercmp
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 = []
		pkg_str = self._db._pkg_str
		cp_list = self._db.cp_list

		for cp in self._db.cp_all():
			for cpv in cp_list(cp):
				# NOTE: Create SLOT atoms even when there is only one
				# SLOT installed, in order to avoid the possibility
				# of unwanted upgrades as reported in bug #338959.
				pkg = pkg_str(cpv, None)
				atom = Atom("%s:%s" % (pkg.cp, pkg.slot))
				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, exclude_files=None, files=None):
		super(OwnerSet, self).__init__()
		self._db = vardb
		self._exclude_files = exclude_files
		self._files = files

	def mapPathsToAtoms(self, paths, exclude_paths=None):
		"""
		All paths must have $EROOT stripped from the left side.
		"""
		rValue = set()
		vardb = self._db
		pkg_str = vardb._pkg_str
		if exclude_paths is None:
			for link, p in vardb._owners.iter_owners(paths):
				pkg = pkg_str(link.mycpv, None)
				rValue.add("%s:%s" % (pkg.cp, pkg.slot))
		else:
			all_paths = set()
			all_paths.update(paths)
			all_paths.update(exclude_paths)
			exclude_atoms = set()
			for link, p in vardb._owners.iter_owners(all_paths):
				pkg = pkg_str(link.mycpv, None)
				atom = "%s:%s" % (pkg.cp, pkg.slot)
				rValue.add(atom)
				if p in exclude_paths:
					exclude_atoms.add(atom)
			rValue.difference_update(exclude_atoms)

		return rValue

	def load(self):
		self._setAtoms(self.mapPathsToAtoms(self._files,
			exclude_paths=self._exclude_files))

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

		exclude_files = options.get("exclude-files")
		if exclude_files is not None:
			exclude_files = frozenset(portage.util.shlex_split(exclude_files))
		return cls(vardb=trees["vartree"].dbapi, exclude_files=exclude_files,
			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
		pkg_str = self._vardb._pkg_str
		for cp in self._vardb.cp_all():
			for cpv in cp_list(cp):
				pkg = pkg_str(cpv, None)
				slot_atom = "%s:%s" % (pkg.cp, pkg.slot)
				ebuild = xmatch(xmatch_level, slot_atom)
				if not ebuild:
					continue
				if vercmp(cpv.version, ebuild.version) > 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 UnavailableBinaries(EverythingSet):

	_operations = ('merge', 'unmerge',)

	description = "Package set which contains all installed " + \
		"packages for which corresponding binary packages " + \
		"are not available."

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

	def _filter(self, atom):
		inst_pkg = self._db.match(atom)
		if not inst_pkg:
			return False
		inst_cpv = inst_pkg[0]
		return not self._metadatadb.cpv_exists(inst_cpv)

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

		metadatadb = options.get("metadata-source", "bintree")
		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"]
	_aux_keys = ('BUILD_TIME',)

	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]
		try:
			date, = self._db.aux_get(cpv, self._aux_keys)
			date = int(date)
		except (KeyError, ValueError):
			return bool(self._mode == "older")
		age = (time.time() - date) / (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 DateSet(EverythingSet):
	_operations = ["merge", "unmerge"]
	_aux_keys = ('BUILD_TIME',)

	def __init__(self, vardb, date, mode="older"):
		super(DateSet, self).__init__(vardb)
		self._mode = mode
		self._date = date

	def _filter(self, atom):

		cpv = self._db.match(atom)[0]
		try:
			date, = self._db.aux_get(cpv, self._aux_keys)
			date = int(date)
		except (KeyError, ValueError):
			return bool(self._mode == "older")
		# Make sure inequality is _strict_ to exclude tested package
		if ((self._mode == "older" and date < self._date) \
			or (self._mode == "newer" and date > self._date)):
			return True
		else:
			return False

	def singleBuilder(cls, options, settings, trees):
		vardbapi = trees["vartree"].dbapi
		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)

		formats = []
		if options.get("package") is not None:
			formats.append("package")
		if options.get("filestamp") is not None:
			formats.append("filestamp")
		if options.get("seconds") is not None:
			formats.append("seconds")
		if options.get("date") is not None:
			formats.append("date")

		if not formats:
			raise SetConfigError(_("none of these options specified: 'package', 'filestamp', 'seconds', 'date'"))
		elif len(formats) > 1:
			raise SetConfigError(_("no more than one of these options is allowed: 'package', 'filestamp', 'seconds', 'date'"))

		format = formats[0]

		if (format == "package"):
			package = options.get("package")
			try:
				cpv = vardbapi.match(package)[0]
				date, = vardbapi.aux_get(cpv, ('BUILD_TIME',))
				date = int(date)
			except (KeyError, ValueError):
				raise SetConfigError(_("cannot determine installation date of package %s") % package)
		elif (format == "filestamp"):
			filestamp = options.get("filestamp")
			try:
				date = int(os.stat(filestamp).st_mtime)
			except (OSError, ValueError):
				raise SetConfigError(_("cannot determine 'filestamp' of '%s'") % filestamp)
		elif (format == "seconds"):
			try:
				date = int(options.get("seconds"))
			except ValueError:
				raise SetConfigError(_("option 'seconds' must be an integer"))
		else:
			dateopt = options.get("date")
			try:
				dateformat = options.get("dateformat", "%x %X")
				date = int(time.mktime(time.strptime(dateopt, dateformat)))
			except ValueError:
				raise SetConfigError(_("'date=%s' does not match 'dateformat=%s'") % (dateopt, dateformat))
		return DateSet(vardb=vardbapi, date=date, mode=mode)

	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)
