""" fontTools.misc.classifyTools.py -- tools for classifying things.
"""

from __future__ import print_function, absolute_import
from fontTools.misc.py23 import *

class Classifier(object):

	"""
	Main Classifier object, used to classify things into similar sets.
	"""

	def __init__(self, sort=True):

		self._things = set() # set of all things known so far
		self._sets = [] # list of class sets produced so far
		self._mapping = {} # map from things to their class set
		self._dirty = False
		self._sort = sort

	def add(self, set_of_things):
		"""
		Add a set to the classifier.  Any iterable is accepted.
		"""
		if not set_of_things:
			return

		self._dirty = True

		things, sets, mapping = self._things, self._sets, self._mapping

		s = set(set_of_things)
		intersection = s.intersection(things) # existing things
		s.difference_update(intersection) # new things
		difference = s
		del s

		# Add new class for new things
		if difference:
			things.update(difference)
			sets.append(difference)
			for thing in difference:
				mapping[thing] = difference
		del difference

		while intersection:
			# Take one item and process the old class it belongs to
			old_class = mapping[next(iter(intersection))]
			old_class_intersection = old_class.intersection(intersection)

			# Update old class to remove items from new set
			old_class.difference_update(old_class_intersection)

			# Remove processed items from todo list
			intersection.difference_update(old_class_intersection)

			# Add new class for the intersection with old class
			sets.append(old_class_intersection)
			for thing in old_class_intersection:
				mapping[thing] = old_class_intersection
			del old_class_intersection

	def update(self, list_of_sets):
		"""
		Add a a list of sets to the classifier.  Any iterable of iterables is accepted.
		"""
		for s in list_of_sets:
			self.add(s)

	def _process(self):
		if not self._dirty:
			return

		# Do any deferred processing
		sets = self._sets
		self._sets = [s for s in sets if s]

		if self._sort:
			self._sets = sorted(self._sets, key=lambda s: (-len(s), sorted(s)))

		self._dirty = False

	# Output methods

	def getThings(self):
		"""Returns the set of all things known so far.

		The return value belongs to the Classifier object and should NOT
		be modified while the classifier is still in use.
		"""
		self._process()
		return self._things

	def getMapping(self):
		"""Returns the mapping from things to their class set.

		The return value belongs to the Classifier object and should NOT
		be modified while the classifier is still in use.
		"""
		self._process()
		return self._mapping

	def getClasses(self):
		"""Returns the list of class sets.

		The return value belongs to the Classifier object and should NOT
		be modified while the classifier is still in use.
		"""
		self._process()
		return self._sets


def classify(list_of_sets, sort=True):
	"""
	Takes a iterable of iterables (list of sets from here on; but any
	iterable works.), and returns the smallest list of sets such that
	each set, is either a subset, or is disjoint from, each of the input
	sets.

	In other words, this function classifies all the things present in
	any of the input sets, into similar classes, based on which sets
	things are a member of.

	If sort=True, return class sets are sorted by decreasing size and
	their natural sort order within each class size.  Otherwise, class
	sets are returned in the order that they were identified, which is
	generally not significant.

	>>> classify([]) == ([], {})
	True
	>>> classify([[]]) == ([], {})
	True
	>>> classify([[], []]) == ([], {})
	True
	>>> classify([[1]]) == ([{1}], {1: {1}})
	True
	>>> classify([[1,2]]) == ([{1, 2}], {1: {1, 2}, 2: {1, 2}})
	True
	>>> classify([[1],[2]]) == ([{1}, {2}], {1: {1}, 2: {2}})
	True
	>>> classify([[1,2],[2]]) == ([{1}, {2}], {1: {1}, 2: {2}})
	True
	>>> classify([[1,2],[2,4]]) == ([{1}, {2}, {4}], {1: {1}, 2: {2}, 4: {4}})
	True
	>>> classify([[1,2],[2,4,5]]) == (
	...     [{4, 5}, {1}, {2}], {1: {1}, 2: {2}, 4: {4, 5}, 5: {4, 5}})
	True
	>>> classify([[1,2],[2,4,5]], sort=False) == (
	...     [{1}, {4, 5}, {2}], {1: {1}, 2: {2}, 4: {4, 5}, 5: {4, 5}})
	True
	>>> classify([[1,2,9],[2,4,5]], sort=False) == (
	...     [{1, 9}, {4, 5}, {2}], {1: {1, 9}, 2: {2}, 4: {4, 5}, 5: {4, 5},
	...     9: {1, 9}})
	True
	>>> classify([[1,2,9,15],[2,4,5]], sort=False) == (
	...     [{1, 9, 15}, {4, 5}, {2}], {1: {1, 9, 15}, 2: {2}, 4: {4, 5},
	...     5: {4, 5}, 9: {1, 9, 15}, 15: {1, 9, 15}})
	True
	>>> classes, mapping = classify([[1,2,9,15],[2,4,5],[15,5]], sort=False)
	>>> set([frozenset(c) for c in classes]) == set(
	...     [frozenset(s) for s in ({1, 9}, {4}, {2}, {5}, {15})])
	True
	>>> mapping == {1: {1, 9}, 2: {2}, 4: {4}, 5: {5}, 9: {1, 9}, 15: {15}}
	True
	"""
	classifier = Classifier(sort=sort)
	classifier.update(list_of_sets)
	return classifier.getClasses(), classifier.getMapping()


if __name__ == "__main__":
	import sys, doctest
	sys.exit(doctest.testmod(optionflags=doctest.ELLIPSIS).failed)
