"""Ticker extension for Flask."""
import struct
from flask import current_app

from eventlet import spawn_n
from eventlet.green import zmq

# Context are thread safe already,
# we'll create one global one for all sockets
context = zmq.Context()

class Ticker:
  """Handle ZMQ connection to broker."""
  def __init__(self, app=None, socketio=None):
    self.app = app
    self.socketio = socketio
    if app is not None:
      self.init_app(app)
    spawn_n(self.run) # spawns eventlet co-routine

  @staticmethod
  def init_app(app):
    """Initialise extension."""
    app.config.setdefault('TICKER_URL', "tcp://localhost:7000")
    # We want the connection live forever
    # app.teardown_appcontext(self.teardown)

  def run(self):
    """Connect to ticker server and emit updates."""
    socket = context.socket(zmq.SUB)
    # Set topic filter, this is a binary prefix
    # to check for each incoming message
    # set from server as uchar topic = X
    # We'll subsribe to only tick updates for now
    socket.setsockopt(zmq.SUBSCRIBE, bytes.fromhex('00'))
    with self.app.app_context():
      current_app.logger.debug("Connecting to ticker: %s", current_app.config['TICKER_URL'])
      socket.connect(current_app.config['TICKER_URL'])
      while True:
        raw = socket.recv()
        # unpack bytes https://docs.python.org/3/library/struct.html
        bid, ask = struct.unpack_from('dd', raw, 1) # offset topic
        self.socketio.emit('tick', {'bid': round(bid, 5), 'ask': round(ask, 5)})
    # socket will be cleaned up at garbarge collection