#!/usr/bin/env python3
#-*- coding: utf-8 -*-
##############################################
# Home	: http://netkiller.github.io
# Author: Neo <netkiller@msn.com>
##############################################
import os,io,sys
import logging, configparser
import threading
from optparse import OptionParser, OptionGroup
import time
from datetime import datetime	
import re

class Test(threading.Thread):
	
	def __init__(self, regex, line):
		threading.Thread.__init__(self)
		self.string = line
		self.regex = regex

	def run(self):
		global found, mutex
		threadname = threading.currentThread().getName()
		if not found :
			if re.search(self.regex, self.string):
				mutex.acquire()
				found = True
				mutex.release()
			#print (threadname, found, self.regex, self.string)

class Auditlog():
	def __init__(self, workspace = None, logging = None):
		
		self.basedir=os.path.dirname(os.path.dirname(os.path.abspath(__file__)))	

	def usage(self):
		self.parser.print_help()

	def configure(self,inifile, section = None):
		conf = {}
		try:
			if not os.path.exists(inifile):
				raise Exception('Cannot open file', inifile)
			config = configparser.SafeConfigParser()
			config.read(inifile)

			if section :
				conf = dict(config.items(section))
			else:
				for sect in config.sections():
					conf[sect] = dict(config.items(sect))

		except configparser.NoSectionError as err:
			print("Error: %s %s" %(err, inifile + ' - ' + 'No Module'))
			sys.exit(1)
		except Exception as err:
			print("Error: %s %s" %(err, inifile))
			sys.exit(1)
		
		self.config = conf
	def matching(self, regexs, string):
		global found, mutex
		found = False
		threads = []

		# 创建锁
		mutex = threading.Lock()
		# 创建线程对象
		for regex in regexs:
			threads.append(Test(regex, string.strip()))
			#time.sleep(1)
		# 启动线程
		for t in threads:
			t.start()
		# 等待子线程结束
		for t in threads:
			t.join()
		return(found)

	def filter(self, logfile, regexs):
		with open(logfile) as files:
			for line in files:
				if self.matching(regexs,line) :
				#for regex in regexs:
				#	if re.search(regex, line):
					print(line.strip())
	
	def stdin(self, regexs):
		line=' '
		while line:
			line = sys.stdin.readline()
			if self.matching(regexs,line) :
				print(line.strip())
			#print(line)
			
	def daemon(self, section):
		if not section :
			sys.exit(1)
		try:
			logfile = section['logfile']
			
			exclude_regexs = []
			if 'exclude' in section and section['exclude'] :
				exclude_file = section['exclude']
				if os.path.exists(exclude_file):
					
					with open(exclude_file,'r') as regexs:
						for regex in regexs:
							exclude_regexs.append(regex.strip())
				else:
					raise Exception('Cannot open exclude file', exclude_file)

			else:
				exclude_file = None
			
			include_regexs = []
			if 'include' in section and section['include'] :
				include_file = section['include']
				
				if os.path.exists(include_file):
					with open(include_file,'r') as regexs:
						for regex in regexs:
							include_regexs.append(regex.strip())
				else:
					raise Exception('Cannot open include file', include_file)					
			else:
				include_file = None
			
			#regular = section['regular']

			if os.path.exists(logfile):
				with open(logfile,'r') as logdata:
					#print(regulardata.readlines())
					for line in logdata:
						#print(line)
						#exclude_switch = False
						#for regex in exclude_regexs:
						#	if re.search(regex, line.strip()):
						#		exclude_switch = True
						#		break
						
						if self.matching(exclude_regexs,line) :
							continue
						if include_file :
							if self.matching(include_regexs,line) :
							#for regex in include_regexs:
								#print(regex.strip(), line.strip())
								#if re.search(regex.strip(), line.strip()):
								print(line.strip())
						else:
							print(line.strip())
			else:
				raise Exception('Cannot open log file', logfile)

			#if not os.path.exists(regular):
			#	raise Exception('Cannot open file', regular)
			#regexs = []
			#with open(regular,'r') as regulardata:
			#	for line in regulardata:
			#		regexs.append(line.strip())
			#print(regexs)

		except Exception as err:
			print("Error: %s %s" %(err, ''))
			sys.exit(1)

	def main(self):
		try:
			usage = "usage: %prog [options] <module>"
			usage += "\n  Homepage: https://www.netkiller.cn  Author: Neo <netkiller@msn.com>"
			self.parser = OptionParser(usage, version='0.0.1', description='log filter')

			self.parser.add_option('-d','--daemon', dest='daemon', action='store_true', default=False, help='run as daemon')
			self.parser.add_option("-l", "--logfile", dest="logfile", default=None,help="log file example: /var/log/message")
			self.parser.add_option('-i', '--stdin', dest='stdin', default=False, action='store_true', help='cat file | prog ...')
			self.parser.add_option('-r','--regex', type="string", dest="regex", default=None, help='loading log file matching regex/regexp. example: ^Feb')
			self.parser.add_option('-f','--regular', dest="regular", default=None, help='regular file')
			self.parser.add_option('', "--debug", action="store_true", help="Print debug information")

			(self.options, self.args) = self.parser.parse_args()
			
			if self.options.debug:
				print("===================================")
				print(self.options, self.args)
				print("===================================")

			if self.options.daemon:
				pid = os.fork()
				if pid > 0:
					#self.logging.info('daemon is ok')
					sys.exit(0)
		
			if self.options.logfile :
				if not self.options.regex and not self.options.regular:
					self.usage()
				if self.options.regex:
					regexs = []
					regexs.append(self.options.regex)
					self.filter(self.options.logfile, regexs)
				if self.options.regular:
					regular = self.options.regular
					if not os.path.exists(regular):
						raise Exception('Cannot open file', regular)
					regexs = []
					with open(regular,'r') as regulardata:
						for regex in regulardata:
							regexs.append(regex.strip())

					self.filter(self.options.logfile, regexs)
			elif self.options.stdin :
				regexs = []
				if self.options.regex:
					regexs.append(self.options.regex.strip())
				if self.options.regular:
					regular = self.options.regular
					if not os.path.exists(regular):
						raise Exception('Cannot open file', regular)
					with open(regular,'r') as regulardata:
						for regex in regulardata:
							regexs.append(regex.strip())
				self.stdin(regexs)
			else:
				
				if len(self.args) > 0 and self.args[0] :
					self.configure(self.basedir+'/etc/'+'auditlog.ini', self.args[0])
					section = self.config
					if self.options.debug:
						print(section)
					self.daemon(section)
				else:
					self.usage()
				#	if self.options.debug:
				#		print(self.config)
				#	self.configure(self.basedir+'/etc/'+'auditlog.ini')
				#	for section in self.config:
				#		self.daemon(self.config[section])
		except Exception as err:
			print("%s %s" %(err, ''))
			sys.exit(1)		
if __name__ == '__main__':
	try:
		auditlog = Auditlog()
		auditlog.debug = True
		#auditlog.usage()
		auditlog.main()
	except KeyboardInterrupt:
		print ("Crtl+C Pressed. Shutting down.")