import re
import json
import logging
from channels import Group
from channels.sessions import channel_session
from .models import Room

log = logging.getLogger(__name__)

@channel_session
def ws_connect(message):
    # Extract the room from the message. This expects message.path to be of the
    # form /chat/{label}/, and finds a Room if the message path is applicable,
    # and if the Room exists. Otherwise, bails (meaning this is a some othersort
    # of websocket). So, this is effectively a version of _get_object_or_404.
    try:
        prefix, label = message['path'].decode('ascii').strip('/').split('/')
        if prefix != 'chat':
            log.debug('invalid ws path=%s', message['path'])
            return
        room = Room.objects.get(label=label)
    except ValueError:
        log.debug('invalid ws path=%s', message['path'])
        return
    except Room.DoesNotExist:
        log.debug('ws room does not exist label=%s', label)
        return

    log.debug('chat connect room=%s client=%s:%s', 
        room.label, message['client'][0], message['client'][1])
    
    # Need to be explicit about the channel layer so that testability works
    # This may be a FIXME?
    Group('chat-'+label, channel_layer=message.channel_layer).add(message.reply_channel)
    data = []
    data['handle'] = 'system'
    data['message'] = 'someone Joined the room'
    m = room.messages.create(**data)
    Group('chat-'+label, channel_layer=message.channel_layer).send({'text': json.dumps(m.as_dict())}, immediately=True)
    message.channel_session['room'] = room.label

@channel_session
def ws_receive(message):
    # Look up the room from the channel session, bailing if it doesn't exist
    try:
        label = message.channel_session['room']
        room = Room.objects.get(label=label)
    except KeyError:
        log.debug('no room in channel_session')
        return
    except Room.DoesNotExist:
        log.debug('recieved message, buy room does not exist label=%s', label)
        return

    # Parse out a chat message from the content text, bailing if it doesn't
    # conform to the expected message format.
    try:
        data = json.loads(message['text'])
    except ValueError:
        log.debug("ws message isn't json text=%s", text)
        return
    
    if set(data.keys()) != set(('handle', 'message')):
        log.debug("ws message unexpected format data=%s", data)
        return

    if data:
        log.debug('chat message room=%s handle=%s message=%s', 
            room.label, data['handle'], data['message'])
        m = room.messages.create(**data)

        # See above for the note about Group
        Group('chat-'+label, channel_layer=message.channel_layer).send({'text': json.dumps(m.as_dict())})

@channel_session
def ws_disconnect(message):
    try:
        label = message.channel_session['room']
        room = Room.objects.get(label=label)
        Group('chat-'+label, channel_layer=message.channel_layer).discard(message.reply_channel)
        data = []
        data['handle'] = 'system'
        data['message'] = 'someone Joined the room'
        m = room.messages.create(**data)
        Group('chat-'+label, channel_layer=message.channel_layer).send({'text': json.dumps(m.as_dict())}, immediately=True)
    except (KeyError, Room.DoesNotExist):
        pass

@@ -1294,28 +1294,17 @@
 a = 
-%5B%5D%0A    data%5B
+%7B
 'handle'
 %5D = 
@@ -1295,36 +1295,33 @@
  = %7B'handle'
-%5D = 
+:
 'system'
 %0A    data%5B'm
@@ -1312,18 +1312,10 @@
 tem'
-%0A    data%5B
+, 
 'mes
@@ -1311,36 +1311,33 @@
 stem', 'message'
-%5D = 
+:
 'someone Joined 
@@ -1341,24 +1341,25 @@
 ed the room'
+%7D
 %0A    m = roo
@@ -2984,32 +2984,17 @@
 a = 
-%5B%5D%0A        data%5B
+%7B
 'handle'
 %5D = 
@@ -2993,20 +2993,17 @@
 dle'
-%5D = 
+:
 'system'
 %0A   
@@ -3002,22 +3002,10 @@
 tem'
-%0A        data%5B
+, 
 'mes
@@ -3009,20 +3009,17 @@
 message'
-%5D = 
+:
 'someone
@@ -3011,38 +3011,36 @@
 ssage':'someone 
-Joined
+Left
  the room'%0A     
@@ -3033,16 +3033,17 @@
 he room'
+%7D
 %0A       

check room