import asyncio
import websockets
import json

clients = {}
vars = {}

async def handshake(ws,data):
    project_id = data.get('project_id','')
    user = data.get('user')
    print(f"{project_id} new user connected from {ws.host}:{ws.port}")
    
    if not clients.get(project_id):
        clients[project_id] = []
    clients[project_id].append(ws)
    await get_variables(ws,project_id,user)
    return (project_id,user)

async def get_variables(ws,project_id,user):
    for name,value in vars.get(project_id,{}).items():
        if not name:
            continue
        await ws.send(json.dumps({"method":"set","name":name,"value":value}))

async def set_variable(project_id,var):
    if not vars.get(project_id,''):
        vars[project_id] = {}
    vars[project_id][var.get('name','')] = var.get('value','')
    websockets.broadcast(clients.get(project_id,[]),json.dumps(var))

async def disconnect(project_id,ws):
    print(f"disconnecting {ws.host}:{ws.port}")
    clients.get(project_id,[]).remove(ws)
            

async def process(ws, path):
    project_id = ""
    user = ""
    async for msg in ws:
        print(f"< {user} - {msg}")
        try:
            data = json.loads(msg)
            method = data.get('method','')
            if method == 'handshake':
                project_id,user = await handshake(ws,data)
            if method in ['set','create']:
                await set_variable(project_id,data)
        finally:
            pass
    await disconnect(project_id,ws)

if __name__ == "__main__":
    try:
        start_server = websockets.serve(process, 'localhost', 5000, compression=None)
    finally:
        pass
    asyncio.get_event_loop().run_until_complete(start_server)
    asyncio.get_event_loop().run_forever()