"""The sample demonstrates how to request currency rates and observe changes on every FCM rate source tick
Press Enter to interrupt the observing and stop the sample
"""

import logging
import threading

import win32com.client
from win32com.client import constants

import CELEnvironment
from CELEnvironment import AssertMessage

#region Settings

# Replace it with real login before run
LOGIN = "your_gw_login"
PASSWORD = "your_gw_password"

#Replace it with FCMID of your FCM
MYFCMID = 245

# Events waiting time
TIMEOUT = 50

# Logging settings: specify log level and log format here.
# Set log level to DEBUG to see more internal messages.
# See more information about logging lib usage: https://docs.python.org/3/howto/logging-cookbook.html
CELEnvironment.LOG_LEVEL = logging.INFO
# CELEnvironment.LOG_FORMAT = ...

# CELEnvironment.SinkInternal uses own LOG_LEVEL (which is inherited from the global one) and own LOG_FORMAT.
# You can redefine them as follows:
# CELEnvironment.SinkInternal.LOG_LEVEL = logging.DEBUG
# CELEnvironment.SinkInternal.LOG_FORMAT = ...

LOG = CELEnvironment.GetLogger()

#endregion


class CurrencyRatesReceivingSample(CELEnvironment.CELSinkBase):
    def __init__(self):
        self.eventGatewayIsUp = threading.Event()
        self.eventGatewayIsDown = threading.Event()

    def Init(self, celEnvironment):
        self.celEnvironment = celEnvironment

    def Start(self):
        LOG.info("Connecting to GW")
        self.celEnvironment.cqgCEL.GWLogon(LOGIN, PASSWORD)

        LOG.info("Waiting for GW connection...")
        AssertMessage(self.eventGatewayIsUp.wait(TIMEOUT), "GW connection timeout!")

        self.celEnvironment.cqgCEL.AccountSubscriptionLevel = constants.aslAccountUpdatesAndOrders

        LOG.info("press Enter to stop..")
        input()

        LOG.info("Logoff from GW")
        self.eventGatewayIsDown.clear()
        self.celEnvironment.cqgCEL.GWLogoff()
        AssertMessage(self.eventGatewayIsDown.wait(TIMEOUT), "GW disconnection timeout!")

        LOG.info("Done.")

    def OnGWConnectionStatusChanged(self, newStatus):
        if newStatus == constants.csConnectionUp:
            LOG.info("GW connection is UP!")
            self.eventGatewayIsUp.set()
        elif newStatus == constants.csConnectionDown:
            LOG.info("GW connection is DOWN!")
            self.eventGatewayIsDown.set()

    def OnCurrencyRatesChanged(self, cqgCurrencyRates):
        currencyRates = win32com.client.Dispatch(cqgCurrencyRates)
        LOG.info("OnCurrencyRatesChanged: %d rate(s)", currencyRates.Count)

        rateEURUSD = currencyRates.Item(MYFCMID, "EUR", "USD")
        if rateEURUSD is not None:
            self._dumpCurrency(win32com.client.Dispatch(rateEURUSD))
        rateBTCUSD = currencyRates.Item(MYFCMID, "BTC", "USD")
        if rateBTCUSD is not None:
            self._dumpCurrency(win32com.client.Dispatch(rateBTCUSD))

    def _dumpCurrency(self, currency):
        LOG.info("Currency name %s has rate %f (inverse rate %f)", \
            currency.CurrencyName, currency.Rate, currency.RateInverse)


# If CQGCEL.APIConfiguration must be customized then do it in this function
def CustomAPIConfiguration(APIConfiguration):
    LOG.info("Set UTC time zone. All time values passed to (received from) CQG API should correspond to this setting.")
    APIConfiguration.TimeZoneCode = constants.tzUTC


if __name__ == "__main__":
    CELEnvironment.Start(CurrencyRatesReceivingSample, CustomAPIConfiguration)
