#!/usr/bin/env python3

import json
import logging

from tornado.ioloop import IOLoop
from tornado.options import define, options
from tornado.web import Application
from tornado.websocket import WebSocketHandler

from django.conf import settings
from websocket import create_connection


define('debug', default=False, help='debug mode')
define('host', default='localhost', help='server host')
define('port', default=8888, help='server port')
define('secret', default='secret', help='secret key')


logger = logging.getLogger(__name__)


class WebSocketMixin:
    def _create_ws_connection(self):
        try:
            self.ws = create_connection(settings.WEBSOCKET_URL)
        except:
            logger.exception("Error creating connection to websocket")

    def _send_websocket_message(self, data):
        try:
            self.ws.send(json.dumps(data))
        except:
            logger.exception("Error sending message to websocket")

    def _close_ws_connection(self):
        try:
            self.ws.close()
        except:
            logger.exception("Error closing the websocket")

    def _send_ws_message_close(self, data):
        self._create_ws_connection()
        self._send_websocket_message(data)
        self._close_ws_connection()


class OwltailWebsocketApp(Application):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.websockets = []


class WebSocket(WebSocketHandler):
    def check_origin(self, origin):
        return True

    def open(self):
        self.application.websockets.append(self)

    def on_close(self):
        self.application.websockets.remove(self)

    def on_message(self, message):
        for ws in self.application.websockets:
            if ws == self:
                continue
            ws.write_message(message)


if __name__ == '__main__':
    app = OwltailWebsocketApp(
        handlers=[(r"/websocket", WebSocket)],
        debug=options.debug,
        cookie_secret=options.secret,
    )
    app.listen(options.port)
    IOLoop.current().start()
