# -*- Mode: Python; tab-width: 4 -*-

import regex

class regex_filter:
	"""Simple filter class.
	The `filters' argument is a list of filters.  Each filter
	is a list of regular expressions that will be matched against
	headers in each message"""

	def __init__ (self, filters, do_promote=1):

		self.hit_dict = {}
		for filter in filters:
			self.hit_dict[id(filter)] = 0

		self.filters = filters
		self.do_promote = do_promote

	def scan (self, headers):
		"Return true if there's a match"
		i = 0
		for filter in self.filters:
			if self.try_filter (headers, filter):
				fid = id(filter)
				self.hit_dict[fid] = self.hit_dict[fid] + 1
				if self.do_promote:
					self.promote (i)
				return 1
			i = i + 1
		return 0

	def try_filter (self, headers, f):
		# a multi-regex filter is a logical AND of several regex matches
		# we short-circuit the AND by returning false when one of the regex
		# fails to match.
		for r in f:
			# if all are -1, then this regex fails. return false.
			if not len (filter (lambda x: x!=-1, map (r.search, headers))):
				# any failures, then we don't match
				return 0
		# made it through, we have a hit!
		return 1

	def promote (self, index):
		"move filter #index to the top"
		self.filters.insert (0, self.filters[index])
		del self.filters[index+1]

	def report (self, channel):
		# report on the top 10 hits
		for i in range(10):
			f = self.filters[i]
			channel.push (
				' <%s>: %d hits\r\n' % (
					repr (map (lambda x: x.givenpat, f)),
					self.hit_dict[id(f)]
					)
				)
