#!python

import os
import argparse
from tradesim import app
from tradesim.Setup import download_market_data, analyse_news_data


# [Check parser arguments]
def period(arg):
    try:
        i = int(eval(arg))
        if i <= 0: raise argparse.ArgumentTypeError(
            'must be a positive integer'
        )
        if i < 100: raise argparse.ArgumentTypeError(
            'must be greater than 100 milliseconds'
        )
        return i
    except (NameError, SyntaxError):
        raise argparse.ArgumentTypeError(
            'must be an integer or a maths expression'
        )

def usize(arg):
    try:
        i = int(eval(arg))
        if i <= 0: raise argparse.ArgumentTypeError(
            'must be a positive integer'
        )
        return i
    except (NameError, SyntaxError):
        raise argparse.ArgumentTypeError(
            'must be an positive integer or a maths expression'
        )

def parse_dict(arg, name):
    if len(arg) % 2 != 0:
        print(f'''\
{os.path.basename(__file__)}: error: argument {name}: must be a list of ticker and name
(exemple: ... -c OR.PA \"L\'ORÉAL (OR)\" CS.PA \"AXA (CS)\" ...)
        ''')
        quit()
    return dict(zip(arg[::2],arg[1::2]))


# [Parse arguments]
parser = argparse.ArgumentParser(
    description='Command line interface for tradesim',
    epilog='''
    additional information:
        The tools for manipulating market data are in the tradesim[extra] package.
        Please install these additional dependencies by installing the extra package
        or the yahooquery and notebook dependencies themselves,
        if you don't intend to use your own data.
    ''',
    add_help=False,
)

parser.add_argument(
    'data_path', type=str,
    help='''
        Specify the folder where the data will be stored.
        Create it if it does not exist
    ''',
)

default = parser.add_argument_group('Default values')
default.add_argument(
    '-p','--period', type=period, default=app.d.update_time, metavar='P',
    help=f'Period of time used to update data on the dashboard (in milliseconds) (default: {app.d.update_time})'
)
default.add_argument(
    '-r', '--max-requests', metavar='N',
    type=int, choices=range(1, 12), default=app.d.max_requests,
    help=f'Maximum number of requests the user can make on the dashboard (default: {app.d.max_requests})'
)
default.add_argument(
    '-m', '--money', type=usize, default=app.d.initial_money, metavar='M',
    help=f'Initial money the user has (default: {app.d.initial_money})'
)
default.add_argument(
    '-c', '--companies', type=str, nargs='+', metavar='TICKER NAME',
    help='List of companies used in the interface (couple of ticker and name)'
)
default.add_argument(
    '-i', '--indexes', type=str, nargs='+', metavar='TICKER NAME',
    help='List of indexes used in the interface (couple of ticker and name)'
)

setup = parser.add_argument_group('Setup')
setup.add_argument(
    '-a', '--check-news', action='store_true',
    help='Open a jupyter notebook to analyze the news data'
)
setup.add_argument(
    '--no-news', action='store_true',
    help='Start interface without news file'
)
setup.add_argument('--debug', action='store_true', help='Run in debug mode')


other = parser.add_argument_group('other arguments')
other.add_argument("-h", "--help", action="help", help="Show this help message and exit")

args = parser.parse_args()


# [Update default values]
app.d.data_path = args.data_path
app.d.update_time = args.period
app.d.max_requests = args.max_requests
app.d.initial_money = args.money
if args.companies:
    app.d.companies = parse_dict(args.companies, '-c/--companies')
if args.indexes:
    app.d.indexes = parse_dict(args.indexes, '-i/--indexes')


# [Setup]
path = args.data_path
if not os.path.exists(path):
    print('Creating directory ' + path)
    os.makedirs(path)

if not os.path.exists(os.path.join(path, "news.csv")) and not args.no_news:
    print('\nYou need to add the `news.csv` file into the ' + path + ' folder\n')
    quit()

if args.check_news:
    print('\nOpening jupyter notebook to analyze news data...\n')
    analyse_news_data(args.data_path)
    quit()

if not os.path.exists(os.path.join(path, "market_data.csv"))\
    or not os.path.exists(os.path.join(path, "revenue.csv")):
    print('\nDownloading market data...\n')
    download_market_data()

# [Run Server]
app.set_layout() # Load layout of the app
app.run_server(debug=args.debug)


