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

import portage.glsa as glsa
from portage._sets.base import PackageSet
from portage.versions import vercmp
from portage._sets import get_boolean

__all__ = ["SecuritySet", "NewGlsaSet", "NewAffectedSet", "AffectedSet"]

class SecuritySet(PackageSet):
	_operations = ["merge"]
	_skip_applied = False
	
	description = "package set that includes all packages possibly affected by a GLSA"
		
	def __init__(self, settings, vardbapi, portdbapi, least_change=True):
		super(SecuritySet, self).__init__()
		self._settings = settings
		self._vardbapi = vardbapi
		self._portdbapi = portdbapi
		self._least_change = least_change

	def getGlsaList(self, skip_applied):
		glsaindexlist = glsa.get_glsa_list(self._settings)
		if skip_applied:
			applied_list = glsa.get_applied_glsas(self._settings)
			glsaindexlist = set(glsaindexlist).difference(applied_list)
			glsaindexlist = list(glsaindexlist)
		glsaindexlist.sort()
		return glsaindexlist
		
	def load(self):
		glsaindexlist = self.getGlsaList(self._skip_applied)
		atomlist = []
		for glsaid in glsaindexlist:
			myglsa = glsa.Glsa(glsaid, self._settings, self._vardbapi, self._portdbapi)
			#print glsaid, myglsa.isVulnerable(), myglsa.isApplied(), myglsa.getMergeList()
			if self.useGlsa(myglsa):
				atomlist += ["="+x for x in myglsa.getMergeList(least_change=self._least_change)]
		self._setAtoms(self._reduce(atomlist))
	
	def _reduce(self, atomlist):
		mydict = {}
		for atom in atomlist[:]:
			cpv = self._portdbapi.xmatch("match-all", atom)[0]
			pkg = self._portdbapi._pkg_str(cpv, None)
			cps = "%s:%s" % (pkg.cp, pkg.slot)
			if not cps in mydict:
				mydict[cps] = (atom, cpv)
			else:
				other_cpv = mydict[cps][1]
				if vercmp(cpv.version, other_cpv.version) > 0:
					atomlist.remove(mydict[cps][0])
					mydict[cps] = (atom, cpv)
		return atomlist
	
	def useGlsa(self, myglsa):
		return True

	def updateAppliedList(self):
		glsaindexlist = self.getGlsaList(True)
		applied_list = glsa.get_applied_glsas(self._settings)
		for glsaid in glsaindexlist:
			myglsa = glsa.Glsa(glsaid, self._settings, self._vardbapi, self._portdbapi)
			if not myglsa.isVulnerable() and not myglsa.nr in applied_list:
				myglsa.inject()
	
	def singleBuilder(cls, options, settings, trees):
		least_change = not get_boolean(options, "use_emerge_resolver", False)
		return cls(settings, trees["vartree"].dbapi, trees["porttree"].dbapi, least_change=least_change)
	singleBuilder = classmethod(singleBuilder)
	
class NewGlsaSet(SecuritySet):
	_skip_applied = True
	description = "Package set that includes all packages possibly affected by an unapplied GLSA"

class AffectedSet(SecuritySet):
	description = "Package set that includes all packages affected by an unapplied GLSA"

	def useGlsa(self, myglsa):
		return myglsa.isVulnerable()

class NewAffectedSet(AffectedSet):
	_skip_applied = True
	description = "Package set that includes all packages affected by an unapplied GLSA"
