import socket
import threading
import struct
import cv2
import io
import numpy as np
import traceback as tb
from PIL import Image
from manager import manager
from convertor import Convertor
from multiprocessing import Process, Pool
from detector.detector import MultiPeopleDetector
import gc
from collections import deque as queue
import psutil
from multiprocessing.dummy import Pool as ThreadPool

class ThreadedServer(object):
    def __init__(self, host, port, manager):
        self.host = host
        self.port = port
        self.manager = manager
        self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        self.sock.bind((self.host, self.port))
        #self.showWindow = cv2.namedWindow('Streaming...', cv2.WINDOW_NORMAL)

    def listen(self):
        self.sock.listen(10)

        client, address = self.sock.accept()
        client.settimeout(60)
        self.listenToClient(client, address)

    def listenToClient(self, client, address):
        size = 1024
        data = client.makefile('rb')
        while True:
            try:
                image_len = struct.unpack('<L', data.read(struct.calcsize('<L')))[0]

                if image_len:
                    # Set the response to echo back the recieved data
                    print('image length: '+str(image_len))
                    image_stream = io.BytesIO()
                    image_stream.write(data.read(image_len))
                    image_stream.seek(0)


                    #needed
                    img = Convertor.toCv2Image(image_stream)

                    #cv2.imshow('Streaming...', img)

                    self.manager.push(img)
                    #print('check for anysc:'+str(manager.count()))

                    #print('detectedImageListL: '+str(manager.detectedCount()))
                    '''
                    if manager.getDetectedImage() is not None:
                        #newImg = manager.getDetectedImage()
                        #newImg = newImg.resize(img, (640,480), 1, 1);
                        #cv2.imshow('Streaming...', manager.getDetectedImage())
                        if cv2.waitKey(1) & 0xFF == ord('q'):
                            break
                    '''
                    image_stream.seek(0)
                    image_stream.truncate()
                    #response = data
                    #client.send(response)
                else:
                    continue
            except:
                client.close()
                print(tb.format_exc())
                return False

if __name__ == "__main__":
    #port_num = input("Port? ")
    manager = manager()
    detector = MultiPeopleDetector()
    mySer = ThreadedServer('0.0.0.0',8000,manager)
    showWindow = cv2.namedWindow('Detected', cv2.WINDOW_NORMAL)
    c = Convertor()
    pool = ThreadPool(8)

    threading.Thread(target = mySer.listen,args=() ).start()
    tempqueue = queue()


    while 1:
        print('Debug...'+str(manager.count()))

        print(str(psutil.cpu_percent()))

        if manager.count() > 30:
            imagebyteList = manager.getCopyList()
            results = pool.map(detector.detect, imagebyteList)


            for img in results:
                print('in loop')
                cv2.imshow('Detected', img)
            '''
            tempqueue.append(resultImage)
            #if len(tempqueue) > 10:

            cv2.imshow('Detected', tempqueue.popleft())

            collected = gc.collect()
            print ("Garbage collector: collected %d objects." % (collected))
            if cv2.waitKey(1) & 0xFF == ord('q'):
                break
            '''
