import socket, threading

### THIS IS FIRST VERSION OF G-COUNTER.
###
### https://en.wikipedia.org/wiki/Conflict-free_replicated_data_type#G-Counter_(Grow-only_Counter)
###
### WE USE x,y as message
###
### x is the counter which corresponds to the server
### y is the counter corresponding to the client
###
### Client part is not ready.
### Please use 
###   netcat 127.0.2.1 8888
### to emulate client

class ClientThread(threading.Thread):
    ''' Thread that listen to client '''
    def __init__ (self, clientAddress, clientsocket):
        threading.Thread.__init__ (self)
        self.csocket = clientsocket
        print ("New connection added: ", clientAddress)
    
    def run(self):
        print ("Connection from : ", clientAddress)
        f = self.csocket.makefile()
        for l in f :
          print ('We received : ', l)
          update_state (l)

MY_ID = 0
#  THIS IS OUR STATE
G_COUNTER=[0, 0] # TODO: generalize it to many clients

def update_state (msg) :
   # we receive smth like "[10,0,..]"
   received_state = [ int (x)  for x in msg.split(',') ]
   # TODO: check the sizes
   for i in range (len (G_COUNTER) ):
     G_COUNTER [i] = max ( G_COUNTER[i], received_state[i] )

def send_state (sock) :
   msg = ",".join (  [ str(x) for x in G_COUNTER ] ) + "\n"
   bytes = msg.encode()
   sock.send (bytes)

SERVER_IP = "127.0.2.1"
PORT = 8888
server = socket.socket (socket.AF_INET, socket.SOCK_STREAM)
server.setsockopt (socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server.bind ( (SERVER_IP, PORT) )
print ("Server started")
print ("Waiting for client request..")
server.listen(1)
clientsock, clientAddress = server.accept()
newthread = ClientThread(clientAddress, clientsock)
newthread.start()

print ('Hello!')
print ('i - increment, v - view, s - send')
while True:
  print ('> ');
  comm = input ()
  if (comm == 'i' ):
     G_COUNTER[MY_ID] += 1
  if (comm == 'v' ):
     print ("Counter value is", sum (G_COUNTER))
  if (comm == 's' ):
     send_state (clientsock)
    
