#!/usr/bin/env python3

from datetime import datetime, timedelta
import argparse
import logging
import asyncio

import matplotlib.pyplot as plt

import iso8601

from aiohttp.client_exceptions import ClientError

from cfei.smap import SmapAiohttpInterface


async def main():
    arguments = parse_arguments()
    setup_logging(arguments.verbose)
    logger = logging.getLogger(__name__)

    logger.debug("Using sMAP server %s", arguments.url)
    smap = SmapAiohttpInterface(arguments.url)

    logger.debug("Requesting data between %s and %s", arguments.start, arguments.end)
    try:
        readings = await smap.fetch_readings_intertwined(
            arguments.start,
            arguments.end,
            arguments.where
        )

        logger.debug(
            "Fetched %d readings from %s to %s",
            len(readings),
            readings.index[0],
            readings.index[-1]
        )

        if arguments.csv:
            print(readings.to_csv())

        if arguments.plot:
            figure, ax = plt.subplots()
            marker = '.' if arguments.plot_markers else None
            ax.step(readings.index, readings.values, where='post', marker=marker)

            plt.show()
    except ClientError as e:
        logger.error("%s", e)


def parse_arguments():
    parser = argparse.ArgumentParser(
        description='Fetch data from sMAP'
    )

    now = datetime.utcnow().replace(tzinfo=iso8601.UTC)
    default_end = now
    default_start = now - timedelta(days=1)

    parser.add_argument(
        'where',
        metavar='WHERE',
        type=str,
        help='sMAP query where'
    )
    parser.add_argument(
        '-v', '--verbose',
        action='count',
        help='increase output'
    )
    parser.add_argument(
        '--url',
        type=str,
        required=True,
        help='sMAP archiver URL'
    )
    parser.add_argument(
        '--plot',
        action='store_true',
        default=False,
        help='plot results'
    )
    parser.add_argument(
        '--plot-markers',
        action='store_true',
        default=False,
        help='show plot markers'
    )
    parser.add_argument(
        '--csv',
        action='store_true',
        default=False,
        help='print results to stdout in CSV format'
    )
    parser.add_argument(
        '--start',
        metavar='DATETIME',
        default=default_start,
        type=parse_datetime,
        help='initial time (default: 24h ago)'
    )
    parser.add_argument(
        '--end',
        metavar='DATETIME',
        default=default_end,
        type=parse_datetime,
        help='final time (default: now)'
    )

    return parser.parse_args()


def parse_datetime(text):
    return iso8601.parse_date(text)


def setup_logging(verbose):
    if verbose is None or verbose <= 0:
        level = logging.WARN
    elif verbose == 1:
        level = logging.INFO
    else:
        level = logging.DEBUG

    logging.basicConfig(level=level)


if __name__ == '__main__':
    loop = asyncio.get_event_loop()
    try:
        loop.run_until_complete(main())
    finally:
        loop.close()
