# EnTrance default application start
#
# Copyright (c) 2018 Ensoft Ltd

import argparse, logging, logging.config, sys
import sanic, sanic.response, yaml
from . import WebsocketHandler

log = logging.getLogger(__name__)
location = getattr(sys, '_MEIPASS', '.') + '/' # where pre-canned files live

def start(config):
    """
    Start a simple server with the specified configuration. If an app needs
    more elaborate setup, then just copy this function and modify.
    """
    start_cfg = config['start']
    log.info('Starting app with ' +
             ', '.join(['{}={}'.format(k, v) for k, v in start_cfg.items()]))
    app = sanic.Sanic(log_config=None)
    app.config.RESPONSE_TIMEOUT = 3600
    app.config.KEEP_ALIVE_TIMEOUT = 75

    # Websocket handling
    @app.websocket('/ws')
    async def handle_ws(request, ws):
        log.info('New websocket client')
        ws_handler = WebsocketHandler(ws, config['features'])
        await ws_handler.handle_incoming_requests()

    # Static file handling
    static_dir = location + start_cfg['static_dir']
    app.static('/static', static_dir)
    @app.route('/')
    async def home_page(request):
        return await sanic.response.file(static_dir + '/index.html')

    # Enter event loop
    app.run(host=start_cfg['host'], port=start_cfg['port'])

def parse_args(args):
    """
    Parse command-line arguments
    """
    parser = argparse.ArgumentParser()
    parser.add_argument('-p', '--port',
                        help='override port')
    parser.add_argument('-a', '--addr',
                        help='override bind address')
    parser.add_argument('-d', '--debug', action='store_true',
                        help='debug to console')
    parser.add_argument('-c', '--config', default=location + 'config.yml',
                        help='config file')
    parser.add_argument('-l', '--logging', default=location + 'logging.yml',
                        help='logging definition file')
    return parser.parse_args(args)

def main(*args):
    # Load up preferences
    opts = parse_args(args)
    main_config = yaml.safe_load(open(opts.config).read())
    logging_config = yaml.safe_load(open(opts.logging).read())

    # Apply any command-line overrides
    if opts.port is not None:
        main_config['start']['port'] = opts.port
    if opts.addr is not None:
        main_config['start']['host'] = opts.addr
    if opts.debug:
        logging_config['handlers']['console']['level'] = 'DEBUG'

    # Go
    logging.config.dictConfig(logging_config)
    start(main_config)
    log.info('Closing down gracefully')

if __name__ == '__main__':
    main(*sys.argv[1:])
