import numpy as np
import threading
from threading import Thread
import time
import os
import sys
from datetime import datetime

import cv2
from imagezmq import imagezmq
import boto3
#import playsound
import requests
import imagiz

import cv2
import zmq
import base64
import numpy as np


             
class AVSS():
	def __init__(self):
		# initialize the ImageHub object
		#self.imageHub = imagezmq.ImageHub()
		#self.imageHub = imagezmq.ImageHub(open_port='tcp://192.168.43.98:5556')
		#server=imagiz.Server()

		# Define the codec and create VideoWriter object
		self.fourcc = cv2.VideoWriter_fourcc(*'XVID')

		# sound alarm filename
		self.filename = 'sound/Siren-SoundBible.com-1094437108.wav'
		
		# s3 auth
		self.__access_key_id = 'AKIAJ5D4AP2JAPU7R75A'
		self.__secret_access_key = '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'
		self.__bucket_name = 'avss-videos'
		self.s3 = boto3.client('s3',
		                        aws_access_key_id=self.__access_key_id,
		                        aws_secret_access_key=self.__secret_access_key)

		# sns auth
		self.__sns_access_key_id = 'AKIAQKPTW2NELUNZXLHZ'
		self.__sns_secret_access_key = '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'
		self.sns = boto3.client('sns',
		                        aws_access_key_id=self.__sns_access_key_id,
		                        aws_secret_access_key=self.__sns_secret_access_key,
		                        region_name="us-east-1")
		self.sns.set_sms_attributes(attributes={'DefaultSMSType': 'Transactional'})

		# load our model
		self.net = cv2.dnn.readNetFromCaffe('model/MobileNetSSD_deploy.prototxt.txt', 'model/MobileNetSSD_deploy.caffemodel')

	        
	#	def __sound_alarm(self):
	#		start = datetime.now()
	#		while True:
	#			sec = (datetime.now() - start).seconds	
	#			playsound.playsound(self.filename)
	#
	#			if sec > 8:
	#				print('seconds------', sec)
	#				break

	#	def __send_msg(self, client_number):
		"""
				# send whatsapp alert twilio	
				r = self.__client.messages.create(from_=self.__from_no,
					        	  to=self.__to_no,
							  body='SECURITY ALERT!!! DETECTED SOMEONE BREACHING YOUR SECURITY!"')
		"""
	#		#self.sns.set_sms_attributes(attributes={'DefaultSMSType': 'Transactional'})
	#
	#		r = self.sns.publish(PhoneNumber=client_number,
	#	        Message='ALERT!!! DETECTED SOMEONE BREACHING YOUR SECURITY!')

	#	def __send_video(self, video_file, client_number):
	#		# upload video to s3 and send link
	#		
	#		self.s3.upload_file(video_file, self.__bucket_name,
	#				video_file, ExtraArgs={'ContentType': 'video/avi', 'ACL': 'public-read'})

	#		url =  f'https://avss-videos.s3.ap-south-1.amazonaws.com/{video_file}'
		"""
				r = self.__client.messages.create(from_=self.__from_no,
					        	  to=self.__to_no,
							  body=f'Here is a video clip: {url})
		"""

	#		response = self.sns.publish(PhoneNumber=client_number,
	#									Message=f'Here is a Video clip: {url}')

	#		os.remove(video_file)
	#		print('-------Alerted!!--------')
	
	def detect(self, client_name, soc):
		
		detected = False
		writer = None
		(h, w) = (None, None)
		#self.imageHub = imageHub 		

		time.sleep(2)
		self.lock = threading.Lock()

		# start server and loop over frames from the video stream
		print('Server Started')
		try:
			while True:
				#(client_name, frame) = self.imageHub.recv_image()
				#self.imageHub.send_reply(b'OK')
				with self.lock:

					frame = soc.recv_string()
					img = base64.b64decode(frame)
					npimg = np.frombuffer(img, dtype=np.uint8)
					frame = cv2.imdecode(npimg, 1)

					#message=server.receive()
					#frame=cv2.imdecode(message.image,1)
					#print(client_name)

					if w is None or h is None:
						(h, w) = frame.shape[:2]

					blob = cv2.dnn.blobFromImage(cv2.resize(frame, (300, 300)),
						0.007843, (300, 300), 127.5)
			 
					# obtain detections
					self.net.setInput(blob)
					detections = self.net.forward()

					#current timestamp
					cv2.putText(frame, datetime.now().strftime(
						"%A %d %B %Y %I:%M:%S%p"), (10, frame.shape[0] - 10),
						cv2.FONT_HERSHEY_SIMPLEX, 0.35, (0, 0, 255), 1)

					# loop over the detections
					for i in np.arange(0, detections.shape[2]):
					
						confidence = detections[0, 0, i, 2]

						if confidence > 0.3:
							idx = int(detections[0, 0, i, 1])

							if idx != 15:
								continue

							if not detected:
								# record the start time
								startTime = datetime.now()
							
								#t1 = Thread(target=self.__send_msg, args=(client_number, ))
								#t1.deamon = True
								#t1.start()
								
								#print(requests.post('http://192.168.43.98:8001/alarm'))
							
								#self.imageHub.send_reply(b'OK')
								detected=True
								video_file = f'{startTime.strftime("%A-%d-%B-%Y-%I-%M-%S")} {client_name}.avi'
								writer = cv2.VideoWriter(video_file, self.fourcc, 8, (w, h), True)
								writer.write(frame)

							#box = detections[0, 0, i, 3:7] * np.array([w, h, w, h])
							#(startX, startY, endX, endY) = box.astype("int")
				 
							# display the prediction
							label = "{}: {:.2f}%".format('person', confidence * 100)
							print('--> ', client_name, '-->', label)
							#cv2.rectangle(frame, (startX, startY), (endX, endY), (0, 0, 255), 2)
							#y = startY - 15 if startY - 15 > 15 else startY + 15
							#cv2.putText(frame, label, (startX, y),
							#	cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 2)
					
		
					if detected:
						sec = (datetime.now() - startTime).seconds	
						writer.write(frame)

						if sec >= 10:
							writer.release()
							print('----seconds: ', sec)

							#t3 = Thread(target=self.__send_video, args=(video_file, client_number))
							#t3.deamon = True 
							#t3.start()

							detected = False
							#t1.join()
							#t2.join()
							#t3.join()
			
		except Exception as e:
			print(str(e))

if __name__ == '__main__':

	try:
		# initialize the ImageHub object
		#client1 = imagezmq.ImageHub()
		#client1 = imagezmq.ImageHub(open_port='tcp://192.168.43.98:5556')
	    
	    # initialize the ImageHub object
		#client2 = imagezmq.ImageHub()
		#client2 = imagezmq.ImageHub(open_port='tcp://192.168.43.98:5555')
		context = zmq.Context()
		footage_socket = context.socket(zmq.SUB)
		footage_socket.bind('tcp://*:5555')
		footage_socket.setsockopt_string(zmq.SUBSCRIBE, np.unicode(''))
		# initialize main object
		avss = AVSS()

		

		context = zmq.Context()
		footage_socket2 = context.socket(zmq.SUB)
		footage_socket2.bind('tcp://*:5556')
		footage_socket2.setsockopt_string(zmq.SUBSCRIBE, np.unicode(''))

		t1 = Thread(target=avss.detect, args=('cam1', footage_socket, ))
		t1.deamon = True
		t1.start()

		t2 = Thread(target=avss.detect, args=('ipcam', footage_socket2, ))
		t2.deamon = True
		# t2.start()
		#avss.detect()

	except KeyboardInterrupt:
	    try:
	        sys.exit(0)
	    except SystemExit:
	        os._exit(0)


	
	
