import argparse
import pathlib

import market_trade.constants
import tinkoff_grpc
import json
import time
import grpc
import argparse

# initializing argument parser
argument_parser = argparse.ArgumentParser(prog="shares saver")


# this argument is used for shares info location, it contains the liquidity info
argument_parser.add_argument("-s", "--shares", type=pathlib.Path, dest="shares_data_path", action="store")

# this argument is used to save the output into distinct dir
argument_parser.add_argument("-o", "--output-directory", type=pathlib.Path, dest="output_directory", action="store")


if __name__ == '__main__':
    cli_args = argument_parser.parse_args()

    # filling the shares data path, no other modes are though of
    if cli_args.shares_data_path:
        shares_path = pathlib.Path(cli_args.shares_data_path)
    else:
        raise NotImplementedError("No path provided for shares liquidity data")

    # filling the output directory data path, where the trades would be saved
    if cli_args.output_directory:
        output_data_path = pathlib.Path(cli_args.output_directory)
    else:
        raise NotImplementedError("No path for the output data of shares")

    # loading shares liquidity stats gathered
    with open(shares_path, encoding="utf-8", mode="r") as shares_stats_file:
        sorted_shares_liquidity_stats = json.load(shares_stats_file)

    # getting sorted list by liquidity and extracting first n, where n is subscription limit
    sorted_shares_figis = list(sorted_shares_liquidity_stats.keys())
    most_liquid_figis_limited = sorted_shares_figis[:market_trade.constants.MARKETDATA_CONNECTION_LIMIT_SUBSCRIPTIONS]

    # instantiating a channel
    api_address = market_trade.constants.TINKOFF_API_ADDRESS
    token = market_trade.constants.TINKOFF_BEARER_TOKEN
    authorization_field = market_trade.constants.TINKOFF_AUTHORIZATION_HEADER
    with tinkoff_grpc.Channel(api_address=api_address,
                              token=token,
                              authorization_field=authorization_field) as tinkoff_channel:
        # getting all share objects list
        instrument_service = tinkoff_grpc.InstrumentsService(tinkoff_channel)
        shares = instrument_service.get_shares(market_trade.constants.DEFAULT_INSTRUMENT_STATUS)

        # getting final object of shares
        shares_to_gather = [share for share in shares if share.figi in most_liquid_figis_limited]

        # gathering shares data
        while True:
            time.sleep(1)
            try:
                tinkoff_trades_saver = tinkoff_grpc.savers.TradesSaver(channel=tinkoff_channel,
                                                                       instruments=shares_to_gather,
                                                                       filepath=output_data_path)
                tinkoff_trades_saver.start()
            except grpc.RpcError as grpc_error:
                pass

