import signal
import sys
import select
import socket
import time
import serial

from uspp import *

#-----------------------------------------------
#
#-----------------------------------------------

COM_SPEED=57600
COM_TOUT=1

SERVER_TIME=1.0
CLIENT_TIME=0.05

#-----------------------------------------------
#
#-----------------------------------------------

class Server:
#    def __init__(self):
#        self.open = 0
        
    def open(self,port):
        if self.open == 1:
            return

        self.server=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
        self.server.bind(("",port))
        self.server.listen(1)

        self.open = 1
        
        print "Server is waiting on port", port

    def wait(self):
        if self.open != 1:
            return

        while 1:
            isReadable = [self.server]
            isWritable = []
            isError =[]

            r, w, e = select.select(isReadable,isWritable,isError,SERVER_TIME)

            if r:
                newSocket, newSocketInfo = self.server.accept()
                return newSocket, newSocketInfo
            if w:
                pass
            if e:
                pass
            else:
                pass

    def close(self):
        if self.open != 1:
            return

        self.server.close()

#-----------------------------------------------
#
#-----------------------------------------------

class Client:
#    def __init__(self):
#        self.open = 0
        
    def open(self,host,port):
        self.sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
        try:
            self.sock.connect((host,port))
        except:
            print "Can't connect to", host, port
            sys.exit(0)
            
        self.open = 1
        
        print "Client connected to",host,":",port

    def setSocket(self,sock):
        self.sock=sock
        self.open = 1
        
    def wait(self,com):
        if self.open != 1:
            return
        
        self.com=com
        
        while 1:
            isReadable = [self.sock]
            isWritable = []
            isError =[]

            r, w, e = select.select(isReadable,isWritable,isError,CLIENT_TIME)

            if r:
                t = self.sock.recv(100)
                if t.__len__() == 0:
                    return
                print t.__len__(),"-"
                #print "Read from connection",t
                com.write(t)
            if w:
                pass
            if e:
                pass
            else:
                #print "time"
                comCount = com.inWaiting()
                if comCount:
                    comBuff = com.read(comCount)
                    self.sock.send(comBuff)

    def close(self):
        if self.open != 1:
            return
        
        self.sock.close()

#-----------------------------------------------
#
#-----------------------------------------------

class comServer:
    def start(self,port,comport):
        self.myServer=Server()
        self.myServer.open(port)

        self.myClient=Client()

	self.com=serial.Serial(comport,COM_SPEED,timeout=COM_TOUT)
	self.com.setStopbits(2)
	#self.com=""

        while 1:
            sock, sockInfo = self.myServer.wait()
            print "Got connection from", sockInfo
            self.myClient.setSocket(sock)
            self.myClient.wait(self.com)
            print "Disconnection of", sockInfo

    def close(self):
        self.myServer.close()
        self.myClient.close()
        
#-----------------------------------------------
#
#-----------------------------------------------

class comClient:
    def start(self,host,port,comport):
        self.myClient=Client()
        self.myClient.open(host,port)
        
	self.com=serial.Serial(comport,COM_SPEED,timeout=COM_TOUT)
	self.com.setStopbits(2)
	#self.com=""

        self.myClient.wait(self.com)

    def close(self):
        self.myClient.close()

#-----------------------------------------------
#
#-----------------------------------------------

def signalHandler( signal, frame ):
    print "You pressed Ctrl+C, exit program...."
    
    serialServer.close()
        
    sys.exit(0)

#-----------------------------------------------
#
#-----------------------------------------------

if sys.argv.__len__() == 4:
    #for item in sys.argv:
    #    print item

    if sys.argv[1] == "server":
        runAsServer = 1
        serverPort = int(sys.argv[2])
        comPort = sys.argv[3]
    else:
        runAsServer = 0
        clientHost = sys.argv[1]
        clientPort = int(sys.argv[2])
        comPort = sys.argv[3]
        
    signal.signal( signal.SIGINT, signalHandler )

    if runAsServer:
        serialServer = comServer()
        serialServer.start(serverPort,comPort)
        pass
    else:
        serialServer = comClient()
        serialServer.start(clientHost,clientPort,comPort)
        pass
else:
    print "Usage :"
    print "  programname server <port> <comport>, as server."
    print "  programname <host> <port> <comport>, as client."
    

    

