class BoardListenMessageHandler(tornado.web.RequestHandler):
	@tornado.web.asynchronous
	@authenticate
	def post(self):
		self.mongodb = self.application.settings['_db']
		user		= self.user
		timestamp	= int(self.get_argument('timestamp'))
		exchange	= self.session['exchange']
		self.clean_matured_message(timestamp)
		messages = [ msg['content'] for msg in BoardMessage.get_collection().find(\
					{
					"id":self.session.session_id,
					"timestamp":{"$gt":timestamp}
					},
				sort=[("timestamp",1)]
					)]

		session = self.mongodb.board.find_one({"id":self.session.session_id})

		if len(messages) > 0:
			self.finish(json.dumps(messages))
			return
		else:
			print "Nothing in DB",timestamp,self.user.username


		binding_keys = [self.session['public_key'], self.session['private_key']]
		if self.user.isBot:
			binding_keys.append(self.session['bot_key'])


		self.channel= PersistentChannel(
				self.application.channel,
				str(session['queue']), exchange, binding_keys, self,arguments = {"x-expires":int(600000)})
		self.channel.add_message_action(self.message_call_back, None)
		self.channel.connect()
		self.closed = False

	def clean_matured_message(self, timestamp):
		BoardMessage.get_collection().remove({
						"id":self.session.session_id,
						'timestamp':{'$lte':timestamp}
						})

	def on_connection_close(self):
		self.channel.close()

	def isClosed(self):
		return self.request.connection.stream.closed()

	def cancel_ok(self):
		if self.request.connection.stream.closed():
			return

		if hasattr(self,"BoardMessage"):
			self.write(json.dumps(self.BoardMessage))
			pika.log.info( "Cancel OK %s",self.user.username)
			print json.dumps(self.BoardMessage)
		else:
			pika.log.info( "Cancel..... %s",self.user.username)
			self.write(json.dumps({}))
		self.finish()

	def message_call_back(self, argument):
		new_messages	= self.channel.get_messages()
		pika.log.info( "MR: %s %s",self.user.username,[ x for x in new_messages ])
		user_id			= self.user.id
		for content in new_messages:
			BoardMessage.new(self.session.session_id,int(content['timestamp']),content)

		if hasattr(self,"BoardMessage"):
			self.BoardMessage.extend(new_messages)
		else:
			self.BoardMessage = new_messages
		#if not self.closed:
		#	self.write(json.dumps(new_messages))
		#	self.finish();
		#	self.closed = True
		print "+++++++++++++++++++++++++++++"
		print self.BoardMessage
		print "+++++++++++++++++++++++++++++"
		self.channel.close();
class BoardListenMessageHandler(tornado.web.RequestHandler):
    @tornado.web.asynchronous
    @authenticate
    def post(self):
        self.mongodb = self.application.settings['_db']
        user = self.user
        timestamp = int(self.get_argument('timestamp'))
        exchange = self.session['exchange']
        self.clean_matured_message(timestamp)
        messages = [ msg['content'] for msg in BoardMessage.get_collection().find(\
           {
           "id":self.session.session_id,
           "timestamp":{"$gt":timestamp}
           },
          sort=[("timestamp",1)]
           )]

        session = self.mongodb.board.find_one({"id": self.session.session_id})

        if len(messages) > 0:
            self.finish(json.dumps(messages))
            return
        else:
            print "Nothing in DB", timestamp, self.user.username

        binding_keys = [
            self.session['public_key'], self.session['private_key']
        ]
        if self.user.isBot:
            binding_keys.append(self.session['bot_key'])

        self.channel = PersistentChannel(self.application.channel,
                                         str(session['queue']),
                                         exchange,
                                         binding_keys,
                                         self,
                                         arguments={"x-expires": int(600000)})
        self.channel.add_message_action(self.message_call_back, None)
        self.channel.connect()
        self.closed = False

    def clean_matured_message(self, timestamp):
        BoardMessage.get_collection().remove({
            "id": self.session.session_id,
            'timestamp': {
                '$lte': timestamp
            }
        })

    def on_connection_close(self):
        self.channel.close()

    def isClosed(self):
        return self.request.connection.stream.closed()

    def cancel_ok(self):
        if self.request.connection.stream.closed():
            return

        if hasattr(self, "BoardMessage"):
            self.write(json.dumps(self.BoardMessage))
            pika.log.info("Cancel OK %s", self.user.username)
            print json.dumps(self.BoardMessage)
        else:
            pika.log.info("Cancel..... %s", self.user.username)
            self.write(json.dumps({}))
        self.finish()

    def message_call_back(self, argument):
        new_messages = self.channel.get_messages()
        pika.log.info("MR: %s %s", self.user.username,
                      [x for x in new_messages])
        user_id = self.user.id
        for content in new_messages:
            BoardMessage.new(self.session.session_id,
                             int(content['timestamp']), content)

        if hasattr(self, "BoardMessage"):
            self.BoardMessage.extend(new_messages)
        else:
            self.BoardMessage = new_messages
        #if not self.closed:
        #	self.write(json.dumps(new_messages))
        #	self.finish();
        #	self.closed = True
        print "+++++++++++++++++++++++++++++"
        print self.BoardMessage
        print "+++++++++++++++++++++++++++++"
        self.channel.close()
class BoardListenMessageSocketHandler(tornado.websocket.WebSocketHandler):
#TODO Merge these code with long-polling functions. avoid frequently db access
	@authenticate
	def open(self):
		print "WebSocket opened","x" * 20
		self.mongodb = self.application.settings['_db']
		user		= self.user
		exchange	= self.session['exchange']

		messages = [ msg.content for msg in BoardMessage.find_all(id=self.session.session_id)]
		if len(messages) > 0:
			self.write_message(json.dumps(messages["message-list"]))

		session = self.mongodb.board.find_one({"id":self.session.session_id})

		self.mongoSession = session
		self.messagesBuffer = messages
		binding_keys= (self.session['public_key'], self.session['private_key'])
		print "QUEUE NAME",session['queue']
		self.channel= PersistentChannel(
				self.application.channel,
				str(session['queue']), exchange, binding_keys, self,arguments = {"x-expires":int(600000)})
		self.channel.add_message_action(self.message_call_back, None)
		self.channel.connect()
		self.lastestTimestamp = 0
		self._isClosed = False

	def clean_matured_message(self, timestamp):
		self.lastestTimestamp = timestamp
		self.messagesBuffer = filter(lambda x: int(x['timestamp']) > timestamp, self.messagesBuffer)


	def isClosed(self):
		return self._isClosed

	def on_connection_close(self):
		self._isClosed = True
		DatabaseConnection()[BoardMessage.table_name].remove({
						"id":self.session.session_id,
						'timestamp':{'$lte':self.lastestTimestamp}
						})

		id			= self.session.session_id
		for content in self.messagesBuffer:
			BoardMessage.new(id,int(content['timestamp']),content)
		self.channel.close()

	def message_call_back(self, argument):
		new_messages	= self.channel.get_messages()
		print "=======================Mr.%s's Message============================" % (self.user.username)
		print "+++++++++++++++++++++++++++++++++++"
		print new_messages
		print "+++++++++++++++++++++++++++++++++++"

		if self.isClosed():
			for msg in new_messages:
				BoardMessage.new(id,int(content['timestamp']),msg)
		else:
			self.messagesBuffer.extend(new_messages)
			self.write_message(json.dumps(new_messages))
		#board_messages	= self.mongodb.board.find_one({"user_id": user_id})
		#board_messages["message-list"].extend(new_messages)
		#self.mongodb.board.save(board_messages)
		#self.board_messages = board_messages["message-list"]
		#self.mongoSession = board_messages


	def on_message(self, message):
		msg = json.loads(message)
		if 'timestamp' in msg:
			timestamp	= int(msg['timestamp'])
			self.clean_matured_message(timestamp)
		elif 'action' in msg:
			message					= msg
			message['user_id']		= str(self.session['user_id'])
			message['method']		= 'action'
			message['private_key']	= self.session['private_key']
			message['room_id']		= str(self.mongoSession['room_id'])
			self.channel.publish_message("dealer", json.dumps(message));

	def cancel_ok(self):
		pass

	def on_close(self):
		self.channel.close();
		print "WebSocket closed"

	def allow_draft76(self):
		return True
class BoardListenMessageSocketHandler(tornado.websocket.WebSocketHandler):
    #TODO Merge these code with long-polling functions. avoid frequently db access
    @authenticate
    def open(self):
        print "WebSocket opened", "x" * 20
        self.mongodb = self.application.settings['_db']
        user = self.user
        exchange = self.session['exchange']

        messages = [
            msg.content
            for msg in BoardMessage.find_all(id=self.session.session_id)
        ]
        if len(messages) > 0:
            self.write_message(json.dumps(messages["message-list"]))

        session = self.mongodb.board.find_one({"id": self.session.session_id})

        self.mongoSession = session
        self.messagesBuffer = messages
        binding_keys = (self.session['public_key'],
                        self.session['private_key'])
        print "QUEUE NAME", session['queue']
        self.channel = PersistentChannel(self.application.channel,
                                         str(session['queue']),
                                         exchange,
                                         binding_keys,
                                         self,
                                         arguments={"x-expires": int(600000)})
        self.channel.add_message_action(self.message_call_back, None)
        self.channel.connect()
        self.lastestTimestamp = 0
        self._isClosed = False

    def clean_matured_message(self, timestamp):
        self.lastestTimestamp = timestamp
        self.messagesBuffer = filter(lambda x: int(x['timestamp']) > timestamp,
                                     self.messagesBuffer)

    def isClosed(self):
        return self._isClosed

    def on_connection_close(self):
        self._isClosed = True
        DatabaseConnection()[BoardMessage.table_name].remove({
            "id":
            self.session.session_id,
            'timestamp': {
                '$lte': self.lastestTimestamp
            }
        })

        id = self.session.session_id
        for content in self.messagesBuffer:
            BoardMessage.new(id, int(content['timestamp']), content)
        self.channel.close()

    def message_call_back(self, argument):
        new_messages = self.channel.get_messages()
        print "=======================Mr.%s's Message============================" % (
            self.user.username)
        print "+++++++++++++++++++++++++++++++++++"
        print new_messages
        print "+++++++++++++++++++++++++++++++++++"

        if self.isClosed():
            for msg in new_messages:
                BoardMessage.new(id, int(content['timestamp']), msg)
        else:
            self.messagesBuffer.extend(new_messages)
            self.write_message(json.dumps(new_messages))
        #board_messages	= self.mongodb.board.find_one({"user_id": user_id})
        #board_messages["message-list"].extend(new_messages)
        #self.mongodb.board.save(board_messages)
        #self.board_messages = board_messages["message-list"]
        #self.mongoSession = board_messages

    def on_message(self, message):
        msg = json.loads(message)
        if 'timestamp' in msg:
            timestamp = int(msg['timestamp'])
            self.clean_matured_message(timestamp)
        elif 'action' in msg:
            message = msg
            message['user_id'] = str(self.session['user_id'])
            message['method'] = 'action'
            message['private_key'] = self.session['private_key']
            message['room_id'] = str(self.mongoSession['room_id'])
            self.channel.publish_message("dealer", json.dumps(message))

    def cancel_ok(self):
        pass

    def on_close(self):
        self.channel.close()
        print "WebSocket closed"

    def allow_draft76(self):
        return True