
from __future__ import unicode_literals
from datetime import datetime
from tornado.escape import json_encode, json_decode
from spotipy import Spotify
import tornado.ioloop, tornado.web, tornado.websocket, tornado.template
import random, string, logging, uuid, subprocess, pykka, ast, logging, json, urllib, urllib2, mem

logger = logging.getLogger(__name__)

class WebsocketHandler(tornado.websocket.WebSocketHandler):
    
    # initiate (not the actual object __init__, but run shortly after)
    def initialize(self, core, config):
        self.core = core  
        self.config = config  

    def check_origin(self, origin):
        return True
        
    def select_subprotocol(self, subprotocols):

        # select one of our subprotocol elements and return it. This confirms the connection has been accepted.
        protocols = mem.iris.digest_protocol( subprotocols )

        # if we've auto-generated some ids, the provided subprotocols was a string, so just return it right back
        # this allows a connection to be completed
        if protocols['generated']:
            return subprotocols[0]
            
        # otherwise, just return one of the supplied subprotocols
        else:
            return protocols['clientid']

    def open(self):
    
        # decode our connection protocol value (which is a payload of id/name from javascript)
        protocolElements = mem.iris.digest_protocol(self.request.headers.get('Sec-Websocket-Protocol', []))

        connection_id = protocolElements['connection_id']
        clientid = protocolElements['clientid']
        self.connection_id = connection_id
        username = protocolElements['username']
        created = datetime.strftime(datetime.now(), '%Y-%m-%d %H:%M:%S')

        # construct our client object, and add to our list of connections
        client = {
            'clientid': clientid,
            'connection_id': connection_id,
            'username': username,
            'ip': self.request.remote_ip,
            'created': created
        }

        # add to connections
        mem.iris.add_connection(connection_id, self, client)
 

    def on_message(self, message):
        
        message = json_decode(message)

        if 'data' in message:
            data = message['data']
        else:
            data = {}

        data['connection_id'] = self.connection_id

        if 'request_id' in message:
            request_id = message['request_id']
        else:
            request_id = False

        # call the method, as specified in payload
        if 'method' in message:

            # make sure the method exists
            if hasattr(mem.iris, message['method']):

                # make the call, and return it's response
                response = getattr(mem.iris, message['method'])(data)
                if response:
                    response['request_id'] = request_id
                    mem.iris.send_message(self.connection_id, response)
            else:
                response = {
                    'error': 'Method "'+message['method']+'" does not exist',
                    'request_id': request_id
                }
                mem.iris.send_message(self.connection_id, response)
        else:
            response = {
                'error': 'Method key missing from request',
                'request_id': request_id
            }
            mem.iris.send_message(self.connection_id, response)


    def on_close(self):
        mem.iris.remove_connection(self.connection_id)





        
class HttpHandler(tornado.web.RequestHandler):

    def set_default_headers(self):
        self.set_header("Access-Control-Allow-Origin", "*")

    def initialize(self, core, config):
        self.core = core
        self.config = config
    
    def get(self, slug=None):

        # make sure the method exists
        if hasattr(mem.iris, slug):

            # make the call, and return it's response
            self.write(getattr(mem.iris, slug)({}))
        else:
            self.write({
                'error': 'Method "'+slug+'" does not exist'
            })
        
