"""The sample demonstrates how to get instrument properties in new mode"""

import logging
import threading

from tabulate import tabulate
from win32com.client import Dispatch, constants

import CELEnvironment

# region Settings

# Replace it with enabled symbol
SYMBOL = "DD"

# 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 InstrumentPropertiesNewMode(CELEnvironment.CELSinkBase):
    def __init__(self):
        self.eventDone = threading.Event()

    def Init(self, celEnvironment):
        self.celEnvironment = celEnvironment

    def Start(self):
        LOG.info("Request instrument properties for %s", SYMBOL)
        request = self.celEnvironment.cqgCEL.CreateInstrumentRequest()
        request.Symbol = SYMBOL
        # Turn subscription to quotes and DOM off because we need just instrument properties
        request.QuoteLevel = constants.qsNone
        request.PropertyLevel = constants.psNone
        request.DOMStatus = False

        self.celEnvironment.cqgCEL.SubscribeNewInstrument(request)

        self.eventDone.wait(10)

    def OnDataError(self, cqgError, errorDescription):
        if cqgError is not None:
            error = Dispatch(cqgError)
            LOG.error("OnDataError: Code: %d Description: %s", error.Code, error.Description)

        self.eventDone.set()

    def OnInstrumentResolved(self, symbol, cqgInstrument, cqgError):
        if cqgError is not None:
            error = Dispatch(cqgError)
            LOG.error("OnInstrumentResolved error: Error code: %d Description: %s", error.Code, error.Description)
            self.eventDone.set()
            return

        instrument = Dispatch(cqgInstrument)
        LOG.info("OnInstrumentResolved: Symbol: %s", symbol)
        properties = Dispatch(instrument.Properties)
        data = [[prop.Name, prop.Value] for prop in properties]
        LOG.info("Instrument properties:\n%s\n", tabulate(data, headers=["Name", "Value"]))

        sessions = Dispatch(instrument.Sessions)
        data = [[s.Number, s.Name, s.StartTime.strftime("%H:%M:%S"), s.EndTime.strftime("%H:%M:%S")] for s in sessions]
        LOG.info(
            "Current sessions (description is valid from %s till %s):\n%s\n",
            sessions.DescriptionStart.strftime("%m/%d/%Y %H:%M"),
            sessions.DescriptionEnd.strftime("%m/%d/%Y %H:%M"),
            tabulate(data, headers=["#", "Name", "StartTime", "EndTime"]),
        )

        self.eventDone.set()


# If CQGCEL.APIConfiguration must be customized then do it in this function
def CustomAPIConfiguration(APIConfiguration):
    # http://partners.cqg.com/sites/default/files/docs/CQGAPI_4.0R/webframe.html#CQG~CQGAPIConfig~NewInstrumentMode.html
    APIConfiguration.NewInstrumentMode = True


if __name__ == "__main__":
    CELEnvironment.Start(InstrumentPropertiesNewMode, CustomAPIConfiguration)
