# Copyright 1999-2016 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2

from __future__ import unicode_literals

import difflib
import re
import portage
from portage import os
from portage.dbapi.porttree import _parse_uri_map
from portage.dbapi.IndexedPortdb import IndexedPortdb
from portage.dbapi.IndexedVardb import IndexedVardb
from portage.localization import localized_size
from portage.output import  bold, bold as white, darkgreen, green, red
from portage.util import writemsg_stdout
from portage.util.iterators.MultiIterGroupBy import MultiIterGroupBy

from _emerge.Package import Package

class search(object):

	#
	# class constants
	#
	VERSION_SHORT=1
	VERSION_RELEASE=2

	#
	# public interface
	#
	def __init__(self, root_config, spinner, searchdesc,
		verbose, usepkg, usepkgonly, search_index=True,
		search_similarity=None, fuzzy=True):
		"""Searches the available and installed packages for the supplied search key.
		The list of available and installed packages is created at object instantiation.
		This makes successive searches faster."""
		self.settings = root_config.settings
		self.verbose = verbose
		self.searchdesc = searchdesc
		self.searchkey = None
		self._results_specified = False
		# Disable the spinner since search results are displayed
		# incrementally.
		self.spinner = None
		self.root_config = root_config
		self.setconfig = root_config.setconfig
		self.fuzzy = fuzzy
		self.search_similarity = (80 if search_similarity is None
			else search_similarity)
		self.matches = {"pkg" : []}
		self.mlen = 0

		self._dbs = []

		portdb = root_config.trees["porttree"].dbapi
		bindb = root_config.trees["bintree"].dbapi
		vardb = root_config.trees["vartree"].dbapi

		if search_index:
			portdb = IndexedPortdb(portdb)
			vardb = IndexedVardb(vardb)

		if not usepkgonly and portdb._have_root_eclass_dir:
			self._dbs.append(portdb)

		if (usepkg or usepkgonly) and bindb.cp_all():
			self._dbs.append(bindb)

		self._dbs.append(vardb)
		self._portdb = portdb
		self._vardb = vardb

	def _spinner_update(self):
		if self.spinner:
			self.spinner.update()

	def _cp_all(self):
		iterators = []
		for db in self._dbs:
			# MultiIterGroupBy requires sorted input
			i = db.cp_all(sort=True)
			try:
				i = iter(i)
			except TypeError:
				pass
			iterators.append(i)
		for group in MultiIterGroupBy(iterators):
			yield group[0]

	def _aux_get(self, *args, **kwargs):
		for db in self._dbs:
			try:
				return db.aux_get(*args, **kwargs)
			except KeyError:
				pass
		raise KeyError(args[0])

	def _aux_get_error(self, cpv):
		portage.writemsg("emerge: search: "
			"aux_get('%s') failed, skipping\n" % cpv,
			noiselevel=-1)

	def _findname(self, *args, **kwargs):
		for db in self._dbs:
			if db is not self._portdb:
				# We don't want findname to return anything
				# unless it's an ebuild in a portage tree.
				# Otherwise, it's already built and we don't
				# care about it.
				continue
			func = getattr(db, "findname", None)
			if func:
				value = func(*args, **kwargs)
				if value:
					return value
		return None

	def _getFetchMap(self, *args, **kwargs):
		for db in self._dbs:
			func = getattr(db, "getFetchMap", None)
			if func:
				value = func(*args, **kwargs)
				if value:
					return value
		return {}

	def _visible(self, db, cpv, metadata):
		installed = db is self._vardb
		built = installed or db is not self._portdb
		pkg_type = "ebuild"
		if installed:
			pkg_type = "installed"
		elif built:
			pkg_type = "binary"
		return Package(type_name=pkg_type,
			root_config=self.root_config,
			cpv=cpv, built=built, installed=installed,
			metadata=metadata).visible

	def _first_cp(self, cp):

		for db in self._dbs:
			if hasattr(db, "cp_list"):
				matches = db.cp_list(cp)
				if matches:
					return matches[-1]
			else:
				matches = db.match(cp)

			for cpv in matches:
				if cpv.cp == cp:
					return cpv

		return None


	def _xmatch(self, level, atom):
		"""
		This method does not expand old-style virtuals because it
		is restricted to returning matches for a single ${CATEGORY}/${PN}
		and old-style virual matches unreliable for that when querying
		multiple package databases. If necessary, old-style virtuals
		can be performed on atoms prior to calling this method.
		"""
		cp = portage.dep_getkey(atom)
		if level == "match-all":
			matches = set()
			for db in self._dbs:
				if hasattr(db, "xmatch"):
					matches.update(db.xmatch(level, atom))
				else:
					matches.update(db.match(atom))
			result = list(x for x in matches if portage.cpv_getkey(x) == cp)
			db._cpv_sort_ascending(result)
		elif level == "match-visible":
			matches = set()
			for db in self._dbs:
				if hasattr(db, "xmatch"):
					matches.update(db.xmatch(level, atom))
				else:
					db_keys = list(db._aux_cache_keys)
					for cpv in db.match(atom):
						try:
							metadata = zip(db_keys,
								db.aux_get(cpv, db_keys))
						except KeyError:
							self._aux_get_error(cpv)
							continue
						if not self._visible(db, cpv, metadata):
							continue
						matches.add(cpv)
			result = list(x for x in matches if portage.cpv_getkey(x) == cp)
			db._cpv_sort_ascending(result)
		elif level == "bestmatch-visible":
			result = None
			for db in self._dbs:
				if hasattr(db, "xmatch"):
					cpv = db.xmatch("bestmatch-visible", atom)
					if not cpv or portage.cpv_getkey(cpv) != cp:
						continue
					if not result or cpv == portage.best([cpv, result]):
						result = cpv
				else:
					db_keys = list(db._aux_cache_keys)
					matches = db.match(atom)
					try:
						db.match_unordered
					except AttributeError:
						pass
					else:
						db._cpv_sort_ascending(matches)

					# break out of this loop with highest visible
					# match, checked in descending order
					for cpv in reversed(matches):
						if portage.cpv_getkey(cpv) != cp:
							continue
						try:
							metadata = zip(db_keys,
								db.aux_get(cpv, db_keys))
						except KeyError:
							self._aux_get_error(cpv)
							continue
						if not self._visible(db, cpv, metadata):
							continue
						if not result or cpv == portage.best([cpv, result]):
							result = cpv
						break
		else:
			raise NotImplementedError(level)
		return result

	def execute(self,searchkey):
		"""Performs the search for the supplied search key"""
		self.searchkey = searchkey

	def _iter_search(self):

		match_category = 0
		self.packagematches = []
		if self.searchdesc:
			self.searchdesc=1
			self.matches = {"pkg":[], "desc":[], "set":[]}
		else:
			self.searchdesc=0
			self.matches = {"pkg":[], "set":[]}
		writemsg_stdout("Searching...\n\n", noiselevel=-1)

		regexsearch = False
		if self.searchkey.startswith('%'):
			regexsearch = True
			self.searchkey = self.searchkey[1:]
		if self.searchkey.startswith('@'):
			match_category = 1
			self.searchkey = self.searchkey[1:]
		fuzzy = False
		if regexsearch:
			self.searchre=re.compile(self.searchkey,re.I)
		else:
			self.searchre=re.compile(re.escape(self.searchkey), re.I)

			# Fuzzy search does not support regular expressions, therefore
			# it is disabled for regular expression searches.
			if self.fuzzy:
				fuzzy = True
				cutoff = float(self.search_similarity) / 100
				seq_match = difflib.SequenceMatcher()
				seq_match.set_seq2(self.searchkey.lower())

				def fuzzy_search(match_string):
					seq_match.set_seq1(match_string.lower())
					return (seq_match.real_quick_ratio() >= cutoff and
						seq_match.quick_ratio() >= cutoff and
						seq_match.ratio() >= cutoff)

		for package in self._cp_all():
			self._spinner_update()

			if match_category:
				match_string  = package[:]
			else:
				match_string  = package.split("/")[-1]

			if self.searchre.search(match_string):
				yield ("pkg", package)
			elif fuzzy and fuzzy_search(match_string):
				yield ("pkg", package)
			elif self.searchdesc: # DESCRIPTION searching
				# Use _first_cp to avoid an expensive visibility check,
				# since the visibility check can be avoided entirely
				# when the DESCRIPTION does not match.
				full_package = self._first_cp(package)
				if not full_package:
					continue
				try:
					full_desc = self._aux_get(
						full_package, ["DESCRIPTION"])[0]
				except KeyError:
					self._aux_get_error(full_package)
					continue
				if not self.searchre.search(full_desc):
					continue

				yield ("desc", package)

		self.sdict = self.setconfig.getSets()
		for setname in self.sdict:
			self._spinner_update()
			if match_category:
				match_string = setname
			else:
				match_string = setname.split("/")[-1]
			
			if self.searchre.search(match_string):
				yield ("set", setname)
			elif self.searchdesc:
				if self.searchre.search(
					self.sdict[setname].getMetadata("DESCRIPTION")):
					yield ("set", setname)

	def addCP(self, cp):
		"""
		Add a specific cp to the search results. This modifies the
		behavior of the output method, so that it only displays specific
		packages added via this method.
		"""
		self._results_specified = True
		if not self._xmatch("match-all", cp):
			return
		self.matches["pkg"].append(cp)
		self.mlen += 1

	def output(self):
		"""Outputs the results of the search."""

		class msg(object):
			@staticmethod
			def append(msg):
				writemsg_stdout(msg, noiselevel=-1)

		msg.append("\b\b  \n[ Results for search key : " + \
			bold(self.searchkey) + " ]\n")
		vardb = self._vardb
		metadata_keys = set(Package.metadata_keys)
		metadata_keys.update(["DESCRIPTION", "HOMEPAGE", "LICENSE", "SRC_URI"])
		metadata_keys = tuple(metadata_keys)

		if self._results_specified:
			# Handle results added via addCP
			addCP_matches = []
			for mytype, matches in self.matches.items():
				for match in matches:
					addCP_matches.append((mytype, match))
			iterator = iter(addCP_matches)

		else:
			# Do a normal search
			iterator = self._iter_search()

		for mtype, match in iterator:
				self.mlen += 1
				masked = False
				full_package = None
				if mtype in ("pkg", "desc"):
					full_package = self._xmatch(
						"bestmatch-visible", match)
					if not full_package:
						masked = True
						full_package = self._xmatch("match-all", match)
						if full_package:
							full_package = full_package[-1]
				elif mtype == "set":
					msg.append(green("*") + "  " + bold(match) + "\n")
					if self.verbose:
						msg.append("      " + darkgreen("Description:") + \
							"   " + \
							self.sdict[match].getMetadata("DESCRIPTION") \
							+ "\n\n")
				if full_package:
					try:
						metadata = dict(zip(metadata_keys,
							self._aux_get(full_package, metadata_keys)))
					except KeyError:
						self._aux_get_error(full_package)
						continue

					desc = metadata["DESCRIPTION"]
					homepage = metadata["HOMEPAGE"]
					license = metadata["LICENSE"]

					if masked:
						msg.append(green("*") + "  " + \
							white(match) + " " + red("[ Masked ]") + "\n")
					else:
						msg.append(green("*") + "  " + bold(match) + "\n")
					myversion = self.getVersion(full_package, search.VERSION_RELEASE)

					mysum = [0,0]
					file_size_str = None
					mycat = match.split("/")[0]
					mypkg = match.split("/")[1]
					mycpv = match + "-" + myversion
					myebuild = self._findname(mycpv)
					if myebuild:
						pkg = Package(built=False, cpv=mycpv,
							installed=False, metadata=metadata,
							root_config=self.root_config, type_name="ebuild")
						pkgdir = os.path.dirname(myebuild)
						mf = self.settings.repositories.get_repo_for_location(
							os.path.dirname(os.path.dirname(pkgdir)))
						mf = mf.load_manifest(
							pkgdir, self.settings["DISTDIR"])
						try:
							uri_map = _parse_uri_map(mycpv, metadata,
								use=pkg.use.enabled)
						except portage.exception.InvalidDependString as e:
							file_size_str = "Unknown (%s)" % (e,)
							del e
						else:
							try:
								mysum[0] = mf.getDistfilesSize(uri_map)
							except KeyError as e:
								file_size_str = "Unknown (missing " + \
									"digest for %s)" % (e,)
								del e

					available = False
					for db in self._dbs:
						if db is not vardb and \
							db.cpv_exists(mycpv):
							available = True
							if not myebuild and hasattr(db, "bintree"):
								myebuild = db.bintree.getname(mycpv)
								try:
									mysum[0] = os.stat(myebuild).st_size
								except OSError:
									myebuild = None
							break

					if myebuild and file_size_str is None:
						file_size_str = localized_size(mysum[0])

					if self.verbose:
						if available:
							msg.append("      %s %s\n" % \
								(darkgreen("Latest version available:"),
								myversion))
						msg.append("      %s\n" % \
							self.getInstallationStatus(mycat+'/'+mypkg))
						if myebuild:
							msg.append("      %s %s\n" % \
								(darkgreen("Size of files:"), file_size_str))
						msg.append("      " + darkgreen("Homepage:") + \
							"      " + homepage + "\n")
						msg.append("      " + darkgreen("Description:") \
							+ "   " + desc + "\n")
						msg.append("      " + darkgreen("License:") + \
							"       " + license + "\n\n")

		msg.append("[ Applications found : " + \
			bold(str(self.mlen)) + " ]\n\n")

		# This method can be called multiple times, so
		# reset the match count for the next call. Don't
		# reset it at the beginning of this method, since
		# that would lose modfications from the addCP
		# method.
		self.mlen = 0

	#
	# private interface
	#
	def getInstallationStatus(self,package):
		installed_package = self._vardb.match(package)
		if installed_package:
			try:
				self._vardb.match_unordered
			except AttributeError:
				installed_package = installed_package[-1]
			else:
				installed_package = portage.best(installed_package)

		else:
			installed_package = ""
		result = ""
		version = self.getVersion(installed_package,search.VERSION_RELEASE)
		if len(version) > 0:
			result = darkgreen("Latest version installed:")+" "+version
		else:
			result = darkgreen("Latest version installed:")+" [ Not Installed ]"
		return result

	def getVersion(self,full_package,detail):
		if len(full_package) > 1:
			package_parts = portage.catpkgsplit(full_package)
			if detail == search.VERSION_RELEASE and package_parts[3] != 'r0':
				result = package_parts[2]+ "-" + package_parts[3]
			else:
				result = package_parts[2]
		else:
			result = ""
		return result

