"""The sample demonstrates detailed DOM data observing via new instrument mode"""

import logging
import threading

import win32com.client

import CELEnvironment

#region Settings

# Replace it with enabled symbol
SYMBOL = "EP"
DOM_BOOK_LIMIT = 10
DETAILED_DOM_LIMIT = 5

# 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 DetailedDOM(CELEnvironment.CELSinkBase):
    def __init__(self):
        self.eventDone = threading.Event()

    def Init(self, celEnvironment):
        self.celEnvironment = celEnvironment

    def Start(self):
        LOG.info("Request DOM for %s", SYMBOL)
        request = self.celEnvironment.cqgCEL.CreateInstrumentRequest()
        request.Symbol = SYMBOL
        request.DOMBBAType = win32com.client.constants.dbtCombined
        request.DOMStatus = True
        request.DOMBookLimit = DOM_BOOK_LIMIT
        request.IncludeDetailedDOM = True
        request.DetailedDOMLimit = DETAILED_DOM_LIMIT

        self.celEnvironment.cqgCEL.SubscribeNewInstrument(request)

        LOG.info("Observing the data...")
        self.eventDone.wait(60)

    def OnDataError(self, cqgError, errorDescription):
        if cqgError is not None:
            error = win32com.client.Dispatch(cqgError)
            LOG.error("OnDataError: Code: %d Description: %s", error.Code, error.Description)

        self.eventDone.set()

    def OnInstrumentDOMChanged(self, cqgInstrument, prevAsks, prevBids):
        instrument = win32com.client.Dispatch(cqgInstrument)
        for ask in instrument.DOMAsks:
            if ask.IsValid:
                LOG.info("ASK Price: %f VolumeFractional %s", ask.Price, ask.VolumeFractional)
                for domOrder in ask.OrdersQueue:
                    LOG.info("     Id: %s VolumeFractional: %s ContributorId: %d Type: %d",
                             domOrder.ID, domOrder.VolumeFractional, domOrder.ContributorID, domOrder.Type)
        for bid in instrument.DOMBids:
            if bid.IsValid:
                LOG.info("     BID Price: %f VolumeFractional %s", bid.Price, bid.VolumeFractional)
                for domOrder in bid.OrdersQueue:
                    LOG.info("         Id: %s VolumeFractional: %s ContributorId: %d Type: %d",
                             domOrder.ID, domOrder.VolumeFractional, domOrder.ContributorID, domOrder.Type)


# If CQGCEL.APIConfiguration must be customized then do it in this function
def CustomAPIConfiguration(APIConfiguration):
    APIConfiguration.NewInstrumentMode = True
    APIConfiguration.DOMUpdatesMode = win32com.client.constants.domUMSnapshot
    APIConfiguration.DOMUpdatesPeriod = 1000


if __name__ == "__main__":
    CELEnvironment.Start(DetailedDOM, CustomAPIConfiguration)
