#!/usr/bin/python3

# import json
from datetime import datetime, timedelta
import logging
import logging.config

from algo.data.common import CompletePriceStream, Symbol
# from algo.config import config
# from algo.constant import Symbol
# from algo.data.reader import PriceStream, get_data_reader
# from algo.strategy.moving_averages import MAStrategyParams, run_simulation
# from algo.trading import PricePoint
# from algo.util import d, now
# from algo.strategy import moving_average_sample
from algo.data.live import get_live_price_stream, get_complete_prices_generator
from algo.data.reader import get_data_reader
from algo.public import get_strategy_by_name
from algo.simulation import simulate_trading, simulate_trading_influx_data
from algo.util import d
from algo.config import config
from algo.data.reporter import InfluxDataReporter, InfluxStrategyOutput, get_cloud_watch_reporter
from algo.scripts import cache_from_influx

logging.config.fileConfig(
    './logging.conf',
    disable_existing_loggers=False
)

log = logging.getLogger(__name__)


# def serialize_data_record(data_record):
#     """
#     input is a FluxRecord
#     """
#     return data_record['result']['_measurement']


# def read_all(data: PriceStream):
#     data_points_counter = 0
#     total_length = 0  # in chars
#     total_ask = 0.0
#     total_bid = 0.0
#     for data_point in data:
#         # log.info('data-point', extra=d(data_point))
#         # log.info('data-point', extra=d(data_point[0].isoformat()))
#         total_ask += data_point[1]
#         total_bid += data_point[2]

#         data_serialized = data_point.to_json()
#         total_length += len(data_serialized)
#         data_points_counter += 1
#     return data_points_counter, total_length, total_ask, total_bid


def try_listener():
    """write the fucking tests"""
    config.set_config({
    })
    price_stream: CompletePriceStream = get_live_price_stream(
        price_reader=get_complete_prices_generator)
    # influx_reporter = get_influx_data_reporter()
    cw_reporter = get_cloud_watch_reporter()
    for price in price_stream:
        log.debug('price-point', extra=d(p=price))
        # influx_reporter.report(price)
        cw_reporter.report(price)


def verify_cache_works():
    data_reader = get_data_reader()
    log.info('loading cached data')
    data_iterator = data_reader.day_data(
        '2022-09-01 00:00:00+00:00', Symbol.JPY
    )
    all_data = list(data_iterator)
    log.info('done')
    log.info('loading influx no cache data')
    no_cahe_iterator = data_reader.day_data_no_cache(
        '2022-09-01 00:00:00+00:00', Symbol.JPY
    )
    data_no_cache = list(no_cahe_iterator)
    log.info('done')
    assert all_data == data_no_cache
    # data_iterator = data_reader.week_data(
    #     '2022-09-04 00:00:00+00:00', Symbol.JPY
    # )

    # data_counter = 0
    # for d in data_iterator:
    #     data_counter += 1
    #     if data_counter % 100 == 0:
    #         log.info('data-counter', extra={'counter': data_counter})


def cache_data():
    data_reader = get_data_reader()
    log.info('loading cached data')
    for s in Symbol:
        log.info('loading data', extra={'s': s})
        data_iterator = data_reader.week_data(
            '2022-10-20 00:00:00+00:00', s
        )
        all_data = list(data_iterator)
        log.info(
            'got-data',
            extra={
                'len': len(all_data),
                'symbol': s
            }
        )


def try_dynamo_cache():
    from algo.data.cache.dynamo import DynamoCache  # pylint: disable=all
    dc = DynamoCache()
    dc.set('test-data', {'d': 12})
    assert {'d': 12} == dc.get('test-data')
    dc.set_lock('sv')
    assert dc.has_lock('sv')
    assert not dc.has_lock('asdf')
    dc.clear_lock('sv')
    assert not dc.has_lock('sv')


def cache_data_from_local_server():
    dr = get_data_reader()
    current_week = datetime.fromisoformat('2022-09-22 00:00:00+00:00')
    end_week = datetime.fromisoformat('2022-10-20 00:00:00+00:00')
    while current_week < end_week:
        log.info('requesting data for the week', extra={
            'week-of': current_week
        })
        for s in Symbol:
            log.info('loading data', extra={'s': s})
            data_iterator = dr.week_data(
                current_week.isoformat(), s
            )
            all_data = list(data_iterator)
            log.info(
                'got-data',
                extra={
                    'len': len(all_data),
                    'symbol': s,
                    'week': current_week
                }
            )

        current_week += timedelta(days=7)


def playgraund():
    log.info('starting simulation')
    strategy = get_strategy_by_name('sample-moving-average')

    if strategy is not None:
        # '2022-11-09':  "simulation-result": [4.826000000000022, 3.057999999999936, 130]
        # '2022-10-10':  "simulation-result": [0.025999999999811507, 1.3840000000000146, 101]
        # simulate_trading(
        #     '2022-10-10', Symbol.JPY,
        #     strategy.module,
        #     strategy.args(4000, 5400)
        # )
        #  '2022-11-09': "simulation-result": [4.826000000000022, 3.057999999999936, 130]
        #  '2022-10-10': "simulation-result": [0.025999999999811507, 1.3840000000000146, 101]
        simulate_trading_influx_data(
            '2022-10-10', Symbol.JPY,
            strategy.module,
            strategy.args(4000, 5400)
        )


if __name__ == '__main__':
    log.info('getting started')
    # playgraund()
    # following is a line for a weekly  data move to  dynamoDB
    cache_from_influx()
    # end of a weekly  data move to  dynamoDB
