# srchPtrn.py
# Created by Rashid Khan  
# Version: 2.0

import time, sys, re, os, fnmatch, csv, shutil


def write_to_file(fh, line_str):
	fh.write(line_str)

def read_f_ln(filename):
        fh = open(filename, 'r')
        f_ln=fh.read()
        fh.close()
        return f_ln


#######
debug=0  # turn off  dubug messages
#debug=1 # turn on  dubug messages

timestr = time.strftime("%Y%m%d-%H%M%S")    ##yield YYYYMMDD-HHMMSS

## these arguments will be passed from unix shell scripts

script_name = sys.argv[0] 
sys.path.append(os.path.dirname(sys.argv[0])) ## directory of script

##put search files in an array
srch_files_a = sys.argv[1].split('|') 
if debug > 0:
	for s in srch_files_a:
		print '\n*****File to search : "'+s+'"'

##put search strings in an array
srch_str1_a = sys.argv[2].split('|') 
if debug > 0:
	for s in srch_str1_a:
		print '\n*****PATTERN : "'+s+'"'


#sys.exit() #testing

		
file_ln_count=0
f_match_count=0
gt_f_match_count=0


output_log='/tmp/srchPtrn-output1.log'   #will generate temp output file 

#open file for script output
fh_out = open(output_log, 'w')



### arrays to count matched strings
p_str_found_count=[]
p_str_found_line=[]

found_flag1=0  ##it will set to 1 if any string in any line will be found for any file
found_flag2=0  ##this flag will set 1 if found_flag1=1 and found 2nd search string in any line for any file

############read last read positions of files
file_last_rd_pos=os.path.dirname(sys.argv[0])+'/srchPtrn.confg'  ##keep the last position file in the script dir

##to save from existing last pos  file
last_read_pos_filename_a = []
last_read_pos_num_a = []

if os.path.isfile(file_last_rd_pos):    #last poistion file exist or not

	#read last reading position file
	with open(file_last_rd_pos) as csvfile:
		readCSV = csv.reader(csvfile, delimiter=',')

        	for row in readCSV:
                	filename = row[0]
                	last_read_pos = row[1]
		
			#create array to use later in matching
                	last_read_pos_filename_a.append(filename)
                	last_read_pos_num_a.append(last_read_pos)
else:
        #create file if it is not there
        read_start_from=0
        fh_lastPos1 = open(file_last_rd_pos, "w")
        fh_lastPos1.close()

fh_lastPos1 = open(file_last_rd_pos, "a")  ##open last read position file to append new/updated values

file_pos_in_arr=0
############end - read last read positions of files#############

##### loop for all files 
for file_str in srch_files_a:     #check for each file string 
	files_path = os.path.dirname(file_str) 		##search directory path
	file_ptrn = os.path.basename(file_str)       ##file search pattern without full path

	
	if debug > 0:
		print '\npy- inside-loop start for file path*****file_ptrn PATTERN : "'+files_path+'"\n'
		print '\npy- inside-loop start for file serach string*****file_ptrn PATTERN : "'+file_ptrn+'"\n'
		print '\npy- inside-loop start for serach string*****PATTERN : "'+file_str+'"\n'
		
	############# start loop for each file ##################

	for file_name in os.listdir(files_path):
		######check if match file pattern
		if fnmatch.fnmatch(file_name, file_ptrn ):  	#if match file pattern
			found_in_old_list=0

			ln= '\n\n========================================='
			write_to_file(fh_out, ln)
			fl_w_path=files_path+'/'+file_name
			ln= '\nProcessing file: '+fl_w_path

			fh_out = open(output_log, "a")
			if debug > 0:
				print '\npy- ',ln  #for testing
			write_to_file(fh_out, ln)
			ln= '\n========================================='
			write_to_file(fh_out, ln)

			file_ln_count=0  ##initialize total line in a file

			if debug > 0:
				print '\npy- file_name:', os.path.basename(file_name)
				print '\npy- file_name_last_pos:', file_last_rd_pos

			total_line_in_file=0
			with open(fl_w_path) as f:
				total_line_in_file=len(f.readlines())
				ln= '\nTotal file lines:'+ str(total_line_in_file)
				write_to_file(fh_out, ln)
			
			#### read last read position for file
			file_pos_in_arr=0
			read_start_from=0
			loc_in_arr=0
			for lp_fn in last_read_pos_filename_a:  ##checking if last position exist in array
				if re.search(fl_w_path, lp_fn):
					found_in_old_list=1
					read_start_from=last_read_pos_num_a[loc_in_arr]  ## last read position
					file_pos_in_arr=loc_in_arr

				loc_in_arr=loc_in_arr+1
				

			if debug > 0:
				print fl_w_path,'\npy-   last read pos: ',read_start_from    ##testing

			######

			#print_start_pos=1
			
			#if file rollover
			#if file is empty
			if int(total_line_in_file) == 0:
				read_start_from=0
			else:
				if int(read_start_from) > int(total_line_in_file):
					read_start_from=1
			
			ln= '\nread_start_from: '+str(read_start_from)
			write_to_file(fh_out, ln)
			
			if debug > 0:
				print '\npy- ',fl_w_path,'after chek rollover-   total_line_in_file: ',total_line_in_file,'\n'    ##testing
				print '\npy- ',fl_w_path,'after chek rollover-  last read pos: ',read_start_from,'\n'    ##testing
			
		
			cnt=0
			#should start processing file
			if int(read_start_from) < int(total_line_in_file):
				
				### arrays to count matched strings
				p_str_found_count=[]

				with open(fl_w_path) as input_data:
					for f_line in input_data:

						file_ln_count=file_ln_count+1
						if debug > 0:
							print '\n2-0file_ln#: '+str(file_ln_count)+'  file_line: '+f_line+'\n'
						
						
						
						if debug > 0:
							print '\npy - chk line counts: file_ln_count: ',str(file_ln_count), 'read_start_from: ', str(read_start_from),'\n'
						
						##read after last read position
						#if file_ln_count > read_start_from:
						if int(file_ln_count) > int(read_start_from):
							if debug > 0:
								print '\npy - inside int(file_ln_count) > int(read_start_from)\n'
								print '\npy - 2-loop will start for serach string*****PATTERN : \n'

								
							############# loop start for serach string  ##########
							srch_str=' '
							for srch_str in srch_str1_a:     #check for each string in current file line
								if debug > 0:
									print '\npy -1 inside-loop start for serach string*****PATTERN : "'+srch_str+'"\n'
										
								#if re.search(srch_str, f_line, re.IGNORECASE):
								if re.search(srch_str, f_line):
										
									p_str_found_count.append(srch_str)   #save in array if match found
									
									line_info=srch_str+': '+file_name+': line#'+str(file_ln_count)+' - '+f_line  #all info of matched string
									p_str_found_line.append(line_info)
									if debug > 0:
										print '\n*****MATCHED - showing full details: '+line_info+'\n'
									
									gt_f_match_count = gt_f_match_count+1   ###grand total  for all matches

									if len(sys.argv) < 3:
										#save line number, whole line in an output file
										ln= '\n'+ str(file_ln_count) + '- matched: '+srch_str+ ' - '+ f_line
										f_match_count =f_match_count +1
										if found_flag1 == 0:   #this flag will set just one time
											found_flag1=1


						##end-if-read after last read position
							############# loop end for serach strings ##########
			######still in block for check if match file pattern


				ln= '\nf_match_count='+str(f_match_count)
				write_to_file(fh_out, ln)
				write_to_file(fh_out, '\n\n')

				#save last position for file
				if debug > 0:
					print '\nsave last position for file: ',file_ln_count
					
				if found_in_old_list < 1:  ##new file in search list
					last_read_pos_filename_a.append(fl_w_path)  ## save file name with full path
					last_read_pos_num_a.append(file_ln_count)  ## save last read pos
					found_in_old_list=0
				else:	
					last_read_pos_num_a[file_pos_in_arr]=file_ln_count  ## save last read pos for existing file

				if debug > 0:
					print '\nFile :',fl_w_path,' - read pos: ', file_ln_count
					


				####### count matching strings
				for index, elem in enumerate(srch_str1_a):

					ln= "Count for matching string '"+ elem+ "' = "+str(p_str_found_count.count(elem) )
					
					if debug > 0:
						print ln
										
					write_to_file(fh_out, '\n\n')
					write_to_file(fh_out, ln)
					write_to_file(fh_out, '\n\n')
					
					if p_str_found_count.count(elem) > 0:
						######## start-print last 5 or less lines of matching string
						#create temp array for line print
						temp1_arr=[]
						matchprint_start_pos=0
						matchprint_end_pos=0
						
						regex=re.compile('^'+elem)
						for ln1 in p_str_found_line:
							if re.match(regex, ln1):
								temp1_arr.append(ln1)
		 

						#matchprint_end_pos=temp1_arr.len()
						matchprint_end_pos=len(temp1_arr)
						if matchprint_end_pos > 5:
							matchprint_start_pos=matchprint_end_pos - 5
						else:
							matchprint_start_pos=0

							
						ln='Last few matching lines are below - format is(<matching_string: <File_name>: line#<Line_num_in_file> - <Actual line from file>) :\n\n'
						write_to_file(fh_out, ln)
						for item in temp1_arr[matchprint_start_pos:matchprint_end_pos]:
							ln=item
							write_to_file(fh_out, '\t\t'+ln)
							
							if debug > 0:
								print '\t\t'+ln 
						######## end-print last 5 or less lines of matching string
				
				
				######
					

			######still in block for check if match file pattern
			else:
				write_to_file(fh_out, '\n')
				ln= '\nFile not searched as last read position '+str(read_start_from)+'  is greater or equal to number of lines in file i.e. '+ str(total_line_in_file)
				write_to_file(fh_out, ln)
				write_to_file(fh_out, '\n\n')


	############# end loop for each file ##################

#system.exit()  #testing
	
##### loop for all files 

#########add updated list for last read positions into file
fh_lastPos1.close()
fh_lastPos1 = open(file_last_rd_pos, "w")

for index, elem in enumerate(last_read_pos_filename_a):
	if debug > 0:
		print 'last_read_pos_num_a[index]: ',str(last_read_pos_num_a[index])
		
	ln= elem+ ","+str(last_read_pos_num_a[index])+"\n" 
	
	if debug > 0:
		print ln
		
	write_to_file(fh_lastPos1, ln)

#########end - add updated list for last read positions


ln = 'Total matching count in all files: '+str(gt_f_match_count)
if debug > 0:
	print ln
write_to_file(fh_out, '\n\n')
write_to_file(fh_out, ln)



fh_out.close()  #close output file
fh_lastPos1.close()

print gt_f_match_count   ##total matches overall
#sys.exit(gt_f_match_count)
##end program

