#!/usr/bin/env python3

"""
Basebox microservices example app

this defines an `app:app` module which is loaded from `main.py`
or directly via `uvicorn app:app`.

in the latter case configuration can only be passed 
via OS environment or an env file (`--env-file`), not TOML.

For further information, check [uvicorn: deployment](https://www.uvicorn.org/deployment/)

"""

# stdlib imports
from os import environ
import argparse
import logging

# dependencies imports
import coloredlogs
import uvicorn

# app imports
import config
import consts


def setup_logging():
    """
    Configure logging from LOG_LEVEL environment variable, defaulting to DEBUG.
    This intentionally does not use the config system to enable log messages
    from config initialization.

    Since logging is taken over by uvicorn, this will only be effective during initial startup.

    :returns: the effective log level
    """
    level = environ.get('LOG_LEVEL', consts.DEFAULT_LOG_LEVEL)
    logger = logging.getLogger(consts.LOG_ROOT)
    coloredlogs.install(level=level, logger=logger)
    return level


def parse_args():
    """
    parse command line arguments
    """
    parser = argparse.ArgumentParser(
        description='Basebox microservice example')
    parser.add_argument('-c', '--config-file', type=str,
                        help='config file')
    return parser.parse_args()


def main():
    """
    application entry point
    """

    # setup logging
    log_level = setup_logging()

    # load config
    args = parse_args()
    config.load(args.config_file)

    # inject our application log root into uvicorn's own log config
    #
    # discussion:
    # https://github.com/tiangolo/fastapi/discussions/7457
    # https://github.com/encode/uvicorn/issues/491
    log_config = uvicorn.config.LOGGING_CONFIG
    log_config["loggers"][consts.LOG_ROOT] = {
        "level": log_level.upper(),
        "handlers": [
            "default"
        ],
    }

    # start server
    uvicorn.run('app:app',
                log_config=log_config,
                port=config.int_val('SERVER_PORT'),
                reload=config.bool_val(
                    'SERVER_AUTORELOAD', 'False'))


if __name__ == "__main__":
    main()