from parameter_util import JSON_BODY, JSON_CONTAINS
from http_util import FAIL, CODE_JSON, CODE_MISSING, CODE_SEMANTIC, CODE_GONE, CODE_CONFLICT
from room_util import ROOM_GET, PLAYERS_GET
from websocket_util import WEBSOCKET_SEND
import base64

import json

def start():
    parameters = JSON_BODY(request)

    if parameters == None:
        return(FAIL(CODE_JSON))

    if not JSON_CONTAINS(parameters, [('room_id', int), ('room_pw', str), ('roles', dict)]):
        return(FAIL(CODE_MISSING))

    room_id = parameters['room_id']
    room_pw = parameters['room_pw']
    roles = parameters['roles']

    room_record = ROOM_GET(room_id, room_pw)

    if not room_record:
        return(FAIL(CODE_SEMANTIC))

    #TODO: Enable
    #if room_record.started:
    #    return(FAIL(CODE_CONFLICT))

    if room_record.closed:
        return(FAIL(CODE_GONE))

    roles = json.dumps(roles)
    rolesb64 = base64.standard_b64encode(roles.encode("ascii"))

    db(db.Room.id == room_record.id).update(started=True, roles=rolesb64)

    WEBSOCKET_SEND(room_record, "roles", rolesb64.decode("utf-8"))

    json_response = {"status": "success"}
    return(response.json(json_response))


def roles():
    parameters = JSON_BODY(request)

    if parameters == None:
        return(FAIL(CODE_JSON))

    if not JSON_CONTAINS(parameters, [('room_id', int), ('room_pw', str), ('user_roles', dict)]):
        return(FAIL(CODE_MISSING))

    room_id = parameters['room_id']
    room_pw = parameters['room_pw']
    user_roles = parameters['user_roles']

    room_record = ROOM_GET(room_id, room_pw)

    if not room_record:
        return(FAIL(CODE_SEMANTIC))

    if room_record.closed:
        return(FAIL(CODE_GONE))

    players = PLAYERS_GET(room_record, True)


    #===========================================
    #Parse Roles for each player
    change = {}

    for player in players:
        playerid = str(player["id"])

        if not playerid in user_roles:
            #We do not have a role change for this player
            continue

        definition = user_roles[playerid]

        if not isinstance(definition, dict):
            return(FAIL(CODE_MISSING))

        if not JSON_CONTAINS(definition, [("role", str), ("prompts", list)]):
            return(FAIL(CODE_MISSING))

        for prompt in definition["prompts"]:
            if not isinstance(prompt, dict):
                return(FAIL(CODE_MISSING))

        change[player["uid"]] = definition
    #===========================================

    #Update roles and prompts on server
    for uid in change:
        promptString = base64.standard_b64encode(json.dumps(change[uid]["prompts"]).encode("ascii")).decode("utf-8")
        db(db.Player.id == uid).update(role=change[uid]["role"], inputs=promptString)

    #Update roles on clients
    websocket_response = base64.standard_b64encode(json.dumps(change).encode("ascii")).decode("utf-8")
    WEBSOCKET_SEND(room_record, "role", websocket_response)

    json_response = {"status": "success"}
    return(response.json(json_response))