import socket
import threading
import struct
from PIL import Image
import cv2
import numpy as np
from io import StringIO
import io
import traceback as tb
class ThreadedServer(object):
    def __init__(self, host, port):
        self.host = host
        self.port = port
        #self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.sock = socket.socket()
        self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        self.sock.bind((self.host, self.port))
        self.streamData = None
        self.fream = None
        cv2.namedWindow('From PI', cv2.WINDOW_NORMAL)

    def listen(self):
        self.sock.listen(0)
        while True:
            #client, address = self.sock.accept()
            try:
                print('creating conn')
                connection = self.sock.accept()[0].makefile('rb')
                print('conn creation finish')
                print('creating thread')
                threading.Thread(target = self.listenToClient,args = (connection,)).start()
                print('thread process finsh')
            except:
                print(tb.format_exc())
                connection.close()
                self.sock.close()
                return False

    def listenToClient(self, connection):
        size = 16384
        while True:
            print('geting data')
            try:
                image_len = struct.unpack('<L', connection.read(struct.calcsize('<L')))[0]
                print(image_len)
                if image_len:
                    data = connection.read(image_len)
                    #data = client(dataLength)
                    image_stream = io.BytesIO()

                    image_stream.write(data)

                    image_stream.seek(0)
                    #print(image_stream.read())
                    print(image_stream.read())
                    image = Image.open(image_stream)
                    open_cv_image = np.array(image)
                    # Convert RGB to BGR
                    open_cv_image = open_cv_image[:, :, ::-1].copy()
                    self.fream = open_cv_image
                    cv2.imshow('From PI', open_cv_image)
                    image_stream.seek(0)
                    image_stream.truncate()

                    #print(data)
                    #image_len = struct.unpack('<L', connection.read(struct.calcsize('<L')))[0]
                    #print(image_len)

                    #client.send(response)

            except:
                print(tb.format_exc())
                connection.close()
                self.sock.close()
                return False


    def getFream(self):
        return self.fream

if __name__ == "__main__":
    #port_num = input("Port? ")
    server = ThreadedServer('0.0.0.0',8000)
    server.listen()
