#!/usr/bin/env python
"""Get order details from TouchBistro.

Usage:
    order [options] fetch <db_path> <order_number>
    order [options] report <db_path> <earliest_date> [<latest_date>]

Options:

 -d, --debug    Print detailed debug logging
 -j, --json     Output a JSON summary for the order
 -c, --csv      Output as CSV
 -f, --file=F   Specify an output file instead of stdout
 --day-boundary=X  Specify a day boundary time [default: 02:00:00]
 --with-loyalty  Include a loyalty report in output

If --with-loyalty is used, duplicate records will exist betweeen order payments
and the loyalty report.

If <latest_date> is omitted, it is assumed to be the same as earliest
date (for a one-day report).

"""
import os
import sys
import logging
import json
from docopt import docopt
from touchbistro.order import Order, get_orders_for_date_range
from touchbistro.reports import (
    loyalty_report, write_order_list_to_csv, write_order_to_csv, write_utf8_bom
)


def write_order(args, order, output):
    "Dump an order in the specified output format"
    if args.get('--csv'):
        write_order_to_csv(output, order)
    else:
        for split in order:
            if args.get('--json'):
                json.dump(
                    split.summary(), output, indent=4,
                    sort_keys=True, default=str)
            else:
                output.writelines(split.receipt_form())


def write_orders(args, order_list, output):
    "Dump orders in the specified output format"
    if args.get('--csv'):
        write_order_list_to_csv(output, order_list)
    else:
        for order in order_list:
            for split in order:
                try:
                    if args.get('--json'):
                        if output == sys.stdout:
                            print(
                                json.dumps(
                                    split.summary(), indent=4, sort_keys=True,
                                    default=str))
                        else:
                            json.dump(
                                split.summary(), output, sort_keys=True,
                                default=str)
                    else:
                        output.writelines(split.receipt_form())
                except Exception as err:
                    raise RuntimeError((
                        "fatal exception while handling order "
                        f"{split.order_number}: {err}"))


if __name__ == '__main__':
    ARGS = docopt(__doc__, version='order 0.1')
    logging.basicConfig()

    if ARGS.get('--debug', False):
        print(ARGS, file=sys.stderr)
        logging.getLogger().setLevel(logging.DEBUG)

    if ARGS.get('fetch', None):
        ORDER = Order(
            ARGS.get('<db_path>'),
            order_number=int(ARGS.get('<order_number>'))
        )

        if ARGS.get('--file'):
            with open(
                    os.path.expanduser(ARGS.get('--file')), 'w',
                    encoding='utf-8') as outfile:
                write_utf8_bom(outfile)
                write_order(ARGS, ORDER, outfile)
        else:
            write_order(ARGS, ORDER, sys.stdout)
    elif ARGS.get('report', None):
        if not ARGS.get('<latest_date>', None):
            ARGS['<latest_date>'] = ARGS.get('<earliest_date>')
        ORDERS = get_orders_for_date_range(
            ARGS.get('<db_path>'),
            earliest_date=ARGS.get('<earliest_date>'),
            latest_date=ARGS.get('<latest_date>', ARGS.get('<earliest_date>')),
            day_boundary=ARGS.get('--day-boundary')
        )
        logging.getLogger().debug("Orders object: %s", ORDERS)
        if ARGS.get('--file'):
            with open(
                    os.path.expanduser(ARGS.get('--file')), 'w',
                    encoding='utf-8') as outfile:
                write_utf8_bom(outfile)
                write_orders(ARGS, ORDERS, outfile)
                if ARGS.get('--with-loyalty'):
                    loyalty_report(
                        ARGS.get('<db_path>'),
                        ARGS.get('<earliest_date>'),
                        ARGS.get('<latest_date>', ARGS.get('<earliest_date>')),
                        ARGS.get('--day-boundary'),
                        outfile,
                        in_csv=ARGS.get('--csv'),
                        in_json=ARGS.get('--json'),
                        order_rept=True)
        else:
            write_orders(ARGS, ORDERS, sys.stdout)
            if ARGS.get('--with-loyalty'):
                loyalty_report(
                    ARGS.get('<db_path>'),
                    ARGS.get('<earliest_date>'),
                    ARGS.get('<latest_date>', ARGS.get('<earliest_date>')),
                    ARGS.get('--day-boundary'),
                    sys.stdout,
                    in_csv=ARGS.get('--csv'),
                    in_json=ARGS.get('--json'),
                    order_rept=True)
    sys.exit(0)
