class MainWindowController(QObject):
    '''
    
    '''

    def __init__(self, zeromq_context, window):
        '''
        Constructor
        '''
        self.zeromq_context = zeromq_context
        self.window = window
        self.timeSeries = TimeSeries()
        self.window.view.setData(self.timeSeries)
        self.presentation = None
        
        
    def incomingBar(self, ticker, bar):
        self.timeSeries.addPoint(bar.timestamp, bar)
        self.window.view.update()
        
    def incomingTick(self, ticker, tick):
        self.timeSeries.addPoint(tick.timestamp.toDatetime(), tick)
        
    def incomingEvent(self):
        self.window.view.update()
        
    def startStream(self, streamParameters):
        if streamParameters['type'] == 'attach':
            self.client = QuotesourceClient(self.zeromq_context, streamParameters['control-ep'])
            self.client.setSummaryCallback(self.incomingBar)
            self.client.setTickCallback(self.incomingTick)
            self.client.setEventCallback(self.incomingEvent)
            try:
                from_time = streamParameters['from']
            except KeyError:
                from_time = None    
                
            try:
                to_time = streamParameters['to']
            except KeyError:
                to_time = None
            
            if self.presentation is None:
                self.presentation = ClusterChartPresentation(streamParameters['cluster-chart/cluster-size'], streamParameters['cluster-chart/bar-length'] * 60)
                self.window.view.setPresentation(self.presentation)
            
            self.client.startStream(streamParameters['source'], streamParameters['ticker-selectors'], from_time, to_time, streamParameters['delay'])
            
            
    def stopAllStreams(self):
        self.client.stopStream()
    
        
 def startStream(self, streamParameters):
     if streamParameters['type'] == 'attach':
         self.client = QuotesourceClient(self.zeromq_context, streamParameters['control-ep'])
         self.client.setSummaryCallback(self.incomingBar)
         self.client.setTickCallback(self.incomingTick)
         self.client.setEventCallback(self.incomingEvent)
         try:
             from_time = streamParameters['from']
         except KeyError:
             from_time = None    
             
         try:
             to_time = streamParameters['to']
         except KeyError:
             to_time = None
         
         if self.presentation is None:
             self.presentation = ClusterChartPresentation(streamParameters['cluster-chart/cluster-size'], streamParameters['cluster-chart/bar-length'] * 60)
             self.window.view.setPresentation(self.presentation)
         
         self.client.startStream(streamParameters['source'], streamParameters['ticker-selectors'], from_time, to_time, streamParameters['delay'])
 def setUp(self):
     self.ctx = zmq.Context()
     self.client = QuotesourceClient(self.ctx, "inproc://control")
     
     self.control = self.ctx.socket(zmq.ROUTER)
     self.control.bind("inproc://control")
class Test(unittest.TestCase):


    def setUp(self):
        self.ctx = zmq.Context()
        self.client = QuotesourceClient(self.ctx, "inproc://control")
        
        self.control = self.ctx.socket(zmq.ROUTER)
        self.control.bind("inproc://control")
        
        
    def tearDown(self):
        self.client.stopStream()
        self.ctx.destroy()
        
    def sendControlResponse(self, json_object):
        self.control.send_multipart([self.peer_id, b'', bytes([MessageType.control.value]), json.dumps(json_object).encode('utf-8')])
        
    def recvControlRequest(self):
        response = self.control.recv_multipart()
        self.peer_id = response[0]
        self.assertEqual(b'', response[1])
        self.assertEqual(bytes([MessageType.control.value]), response[2])
        return json.loads(response[3].decode('utf-8'))
    
    def sendStreamData(self, parts):
        self.control.send_multipart([self.peer_id, b'', bytes([MessageType.stream.value])] + parts)

    def testSummary(self):
        es = EventSpy()
        self.client.setSummaryCallback(es.barCallback)
        self.client.startStream("test-source", ["GAZP"], None, None, 0)
        
        stream_request = self.recvControlRequest()
        self.assertEqual('start', stream_request['command'])
        self.sendControlResponse({'result' : 'success'})
        
        
        bar = Summary(Timestamp(12, 34), Datatype.price,
                      FixedDecimal(10, 120000000), FixedDecimal(10, 0), FixedDecimal(13, 0), FixedDecimal(12, 0),
                      123456, 300)
        self.sendStreamData([b'MOEX:GAZP', bar.toBytes()])
        
        while len(es.bars) == 0: # Wait for incoming bar
            pass
        
        self.assertGreater(len(es.bars), 0)
        
        (ticker, received_bar) = es.bars[0]
        self.assertEqual(b'MOEX:GAZP', ticker)
        self.assertEqual(12, received_bar.timestamp.timestamp)
        self.assertEqual(34, received_bar.timestamp.nsecond)
        self.assertAlmostEqual(10.12, float(received_bar.open))
        self.assertAlmostEqual(10.00, float(received_bar.high))
        self.assertAlmostEqual(13.00, float(received_bar.low))
        self.assertAlmostEqual(12.00, float(received_bar.close))
        self.assertEqual(123456, received_bar.volume)
        self.assertEqual(300, received_bar.period)
    
    def testTick(self):
        es = EventSpy()
        self.client.setTickCallback(es.tickCallback)
        self.client.startStream("test-source", ["GAZP"], None, None, 0)
        
        stream_request = self.recvControlRequest()
        self.assertEqual('start', stream_request['command'])
        self.sendControlResponse({'result' : 'success'})
        
        tick = Tick(Timestamp(12, 34), Datatype.price,
                      FixedDecimal(10, 120000000), -123456)
        self.sendStreamData([b'MOEX:GAZP', tick.toBytes()])
        
        while len(es.ticks) == 0: # Wait for incoming tick
            pass
        
        self.assertGreater(len(es.ticks), 0)
        
        (ticker, received_tick) = es.ticks[0]
        self.assertEqual(b'MOEX:GAZP', ticker)
        self.assertEqual(12, received_tick.timestamp.timestamp)
        self.assertEqual(34, received_tick.timestamp.nsecond)
        self.assertAlmostEqual(10.12, float(received_tick.value))
        self.assertEqual(-123456, received_tick.volume)
        
    def testSummary_severalBarsInOnePacket(self):
        es = EventSpy()
        self.client.setSummaryCallback(es.barCallback)
        self.client.startStream("test-source", ["GAZP"], None, None, 0)
        
        stream_request = self.recvControlRequest()
        self.assertEqual('start', stream_request['command'])
        self.sendControlResponse({'result' : 'success'})
        
        
        bar1 = Summary(Timestamp(12, 34), Datatype.price,
                      FixedDecimal(10, 120000000), FixedDecimal(10, 0), FixedDecimal(13, 0), FixedDecimal(12, 0),
                      123456, 300)
        bar2 = Summary(Timestamp(13, 0), Datatype.price,
                      FixedDecimal(11, 120000000), FixedDecimal(11, 0), FixedDecimal(14, 0), FixedDecimal(13, 0),
                      123000, 300)
        self.sendStreamData([b'MOEX:GAZP', bar1.toBytes() + bar2.toBytes()])
        
        while len(es.bars) == 0: # Wait for incoming bar
            pass
        
        self.assertGreater(len(es.bars), 0)
        
        (ticker, received_bar) = es.bars[0]
        self.assertEqual(b'MOEX:GAZP', ticker)
        self.assertEqual(12, received_bar.timestamp.timestamp)
        self.assertEqual(34, received_bar.timestamp.nsecond)
        self.assertAlmostEqual(10.12, float(received_bar.open))
        self.assertAlmostEqual(10.00, float(received_bar.high))
        self.assertAlmostEqual(13.00, float(received_bar.low))
        self.assertAlmostEqual(12.00, float(received_bar.close))
        self.assertEqual(123456, received_bar.volume)
        self.assertEqual(300, received_bar.period)
        
        (ticker, received_bar) = es.bars[1]
        self.assertEqual(b'MOEX:GAZP', ticker)
        self.assertEqual(13, received_bar.timestamp.timestamp)
        self.assertEqual(0, received_bar.timestamp.nsecond)
        self.assertAlmostEqual(11.12, float(received_bar.open))
        self.assertAlmostEqual(11.00, float(received_bar.high))
        self.assertAlmostEqual(14.00, float(received_bar.low))
        self.assertAlmostEqual(13.00, float(received_bar.close))
        self.assertEqual(123000, received_bar.volume)
        self.assertEqual(300, received_bar.period)
        
    def testTick_severalTicksInOnePacket(self):
        es = EventSpy()
        self.client.setTickCallback(es.tickCallback)
        self.client.startStream("test-source", ["GAZP"], None, None, 0)
        
        stream_request = self.recvControlRequest()
        self.assertEqual('start', stream_request['command'])
        self.sendControlResponse({'result' : 'success'})
        
        tick1 = Tick(Timestamp(12, 34), Datatype.price,
                      FixedDecimal(10, 120000000), -123456)
        
        tick2 = Tick(Timestamp(13, 0), Datatype.price,
                      FixedDecimal(12, 120000000), 123000)
        
        self.sendStreamData([b'MOEX:GAZP', tick1.toBytes() + tick2.toBytes()])
        
        while len(es.ticks) == 0: # Wait for incoming tick
            pass
        
        self.assertGreater(len(es.ticks), 0)
        
        (ticker, received_tick) = es.ticks[0]
        self.assertEqual(b'MOEX:GAZP', ticker)
        self.assertEqual(12, received_tick.timestamp.timestamp)
        self.assertEqual(34, received_tick.timestamp.nsecond)
        self.assertAlmostEqual(10.12, float(received_tick.value))
        self.assertEqual(-123456, received_tick.volume)
        
        (ticker, received_tick) = es.ticks[1]
        self.assertEqual(b'MOEX:GAZP', ticker)
        self.assertEqual(13, received_tick.timestamp.timestamp)
        self.assertEqual(0, received_tick.timestamp.nsecond)
        self.assertAlmostEqual(12.12, float(received_tick.value))
        self.assertEqual(123000, received_tick.volume)