"""

    AUTHOR:

        Khushal P Soonderji

    DATE:

        Saturday, 21st Dec., 2024

    OBJECTIVE:

        To handle all trading related behaviour from one place.

    REFERENCES:

        N/A

    DOWNLOADS:

        N/A

"""


#   *****************************************************************************************************************
#  *****                                                                                                          ****
# ***                                                   IMPORT                                                      ***
#  *****                                                                                                          ****
#   *****************************************************************************************************************


# To make sibling directories accessible for imports:
import sys
sys.path.append(".")
sys.path.append("..")

# My async utils:
from utils_v2.database.async_mysql_v2 import AsyncMySQL
from utils_v2.database.async_mongo_v2 import AsyncMongo
from utils_v2.cache.async_redis_cache_v2 import AsyncRedisCache

# Controllers:
from controllers_v2.core.auth_token import CoreAuthTokenController

# Models:
from models.core.auth_token import CoreAuthTokenModel
from models.api.finstitutions.trading.symbols.list import TradingSymbolListRequestData, TradingSymbolListBrokerResponse

# To work with datatypes:
from typing import List, Any

# To make HTTP requests:
import httpx

# To make abstract classes:
from abc import ABC, abstractmethod


#   *****************************************************************************************************************
#  *****                                                                                                          ****
# ***                                           MACROS / ONE-TIME INIT                                              ***
#  *****                                                                                                          ****
#   *****************************************************************************************************************


# --- Nothing Yet


#   *****************************************************************************************************************
#  *****                                                                                                          ****
# ***                                                VARIABLES                                                      ***
#  *****                                                                                                          ****
#   *****************************************************************************************************************


# --- Nothing Yet


#   *****************************************************************************************************************
#  *****                                                                                                          ****
# ***                                                  FUNCTIONS                                                    ***
#  *****                                                                                                          ****
#   *****************************************************************************************************************


# --- Nothing Yet


#   *****************************************************************************************************************
#  *****                                                                                                          ****
# ***                                                   CLASSES                                                     ***
#  *****                                                                                                          ****
#   *****************************************************************************************************************


class TradingController(CoreAuthTokenController, ABC):

    # ┏┓
    # ┃ ┏┓┏┓┏╋┏┓┓┏┏╋┏┓┏┓
    # ┗┛┗┛┛┗┛┗┛ ┗┻┗┗┗┛┛

    def __init__(
            self,
            cache: AsyncRedisCache = None,
            http_client: httpx.AsyncClient = None,
            alert_url: str = None,
            base_filter: dict = None,
            debug: bool = True,
            debug_prefix: str = "Trading (C) | ",
            debug_only_errors: bool = True
    ):

        """
        This is the foundational controller for all trading/stockbroking services. This is built on top of the
        authorization model, and, in turn, the individual stockbroking clients should be built on top of this.
        :param cache: The object to use for caching results from database calls.
        :param http_client: The HTTP client
        :param base_filter: The basic filter that will be applied to all fetching/updating queries. WARNING: THE BASE
            FILTER WILL ALWAYS BE APPLIED AUTOMATICALLY. SET THIS UP WISELY.
        :param debug: Whether, or not, you would like to print debugging messages:
        :param debug_prefix: The prefix to print with the debugging messages.
        :param debug_only_errors: Whether you would like to print only error messages or all messages.
        :return: None.
        """

        # Declare the service type:
        this_service_type = "stockTrading"

        # Prepare base filter:
        this_filter = {}
        for k, v in (base_filter or {}).items(): this_filter[k] = v
        this_filter["serviceType"] = this_service_type

        # Invoke the parent's constructor:
        CoreAuthTokenController.__init__(
            self,
            cache = cache,
            alert_url = alert_url,
            http_client = http_client,
            base_filter = this_filter,
            debug = debug,
            debug_prefix = debug_prefix,
            debug_only_errors = debug_only_errors
        )

        # Init a variable in a parent:
        self._service_type = this_service_type

    # ┏┓   ┓
    # ┣┫┓┏╋┣┓
    # ┛┗┗┻┗┛┗

    @staticmethod
    @abstractmethod
    async def get_authorization_url(
            **kwargs
    ) -> str:

        """
        To generate an authorization URL for this broker.
        :param kwargs: Any no. of things needed by your broker to generate the URL.
        :return: The authorization URL.
        """

        pass

    @abstractmethod
    async def handle_authorization_callback(
            self,
            sql_conn: AsyncMySQL,
            mongo_data_conn: AsyncMongo,
            inbound_data: dict
    ) -> bool:

        """
        When the end user interacts with their broker's APIs, the broker's servers would usually issue a callback.
        We've seen this in the case of Zerodha Kite and ICICI Breeze. Use this method to handle the callback loop to
        complete the authorization.
        :param sql_conn: The database connection to use to perform this activity.
        :param mongo_data_conn: The database connection to use to perform this activity.
        :param inbound_data: The data that came in from the broker. This could be in the JSON body, query params, etc.
        :return: True if the callback loop was completed successfully, else False.
        """

        pass

    # ┏┳┓     ┓•      ┏┓     ┓   ┓
    #  ┃ ┏┓┏┓┏┫┓┏┓┏┓  ┗┓┓┏┏┳┓┣┓┏┓┃┏
    #  ┻ ┛ ┗┻┗┻┗┛┗┗┫  ┗┛┗┫┛┗┗┗┛┗┛┗┛
    #              ┛     ┛

    @abstractmethod
    async def list_symbols(
            self,
            mongo_data_conn: AsyncMongo,
            auth_token: CoreAuthTokenModel,
            inbound_data: TradingSymbolListRequestData
    ) -> TradingSymbolListBrokerResponse:

        """
        To get the list of tradeable symbols offered by a broker.
        :param mongo_data_conn: The database connection to use to perform this activity.
        :param auth_token: The token that has to be used to fetch the data.
        :param inbound_data: The data that came in with the APi call.
        :return: The structured response form the broker.
        """

        pass


#   *****************************************************************************************************************
#  *****                                                                                                          ****
# ***                                               MAIN PROGRAM                                                    ***
#  *****                                                                                                          ****
#   *****************************************************************************************************************


if __name__ == "__main__":

    pass
