"""
automatically invoked app factory
"""
import logging
import os
from flask import Flask
from flask_cors import CORS

from inventory_provider import environment
from inventory_provider.auth import auth


def create_app(setup_logging=True):
    """
    overrides default settings with those found
    in the file read from env var SETTINGS_FILENAME

    :return: a new flask app instance
    """
    if setup_logging:
        environment.setup_logging()

    required_env_vars = [
        'FLASK_SETTINGS_FILENAME', 'INVENTORY_PROVIDER_CONFIG_FILENAME']

    assert all([n in os.environ for n in required_env_vars]), \
        'environment variables %r must be defined' % required_env_vars

    assert os.path.isfile(os.environ['INVENTORY_PROVIDER_CONFIG_FILENAME']), (
        'config file %r not found' %
        os.environ['INVENTORY_PROVIDER_CONFIG_FILENAME'])

    from inventory_provider import config
    with open(os.environ['INVENTORY_PROVIDER_CONFIG_FILENAME']) as f:
        logging.info(
            'loading config from: %r'
            % os.environ['INVENTORY_PROVIDER_CONFIG_FILENAME'])
        inventory_provider_config = config.load(f)

    app = Flask(__name__)
    CORS(app)

    app.secret_key = 'super secret session key'

    logging.info(
        'initializing Flask with config from: %r' %
        os.environ['FLASK_SETTINGS_FILENAME'])
    app.config.from_envvar('FLASK_SETTINGS_FILENAME')

    app.config['INVENTORY_PROVIDER_CONFIG'] = inventory_provider_config

    # Apply authentication globally to all routes
    @app.before_request
    @auth.login_required
    def secure_before_request():
        # This method is a boilerplate required by the library to enable authentication
        pass

    # IMS based routes

    from inventory_provider.routes import lg
    app.register_blueprint(lg.routes, url_prefix='/lg')

    from inventory_provider.routes import data
    app.register_blueprint(data.routes, url_prefix='/data')

    from inventory_provider.routes import classifier
    app.register_blueprint(classifier.routes, url_prefix='/classifier')

    from inventory_provider.routes import jobs
    app.register_blueprint(jobs.routes, url_prefix='/jobs')

    # end of IMS based routes

    from inventory_provider.routes import default
    app.register_blueprint(default.routes, url_prefix='/')

    from inventory_provider.routes import mic
    app.register_blueprint(mic.routes, url_prefix='/mic')

    from inventory_provider.routes import poller
    app.register_blueprint(poller.routes, url_prefix='/poller')

    from inventory_provider.routes import msr
    app.register_blueprint(msr.routes, url_prefix='/msr')

    from inventory_provider.routes import lnetd
    app.register_blueprint(lnetd.routes, url_prefix='/LnetD')

    from inventory_provider.routes import neteng
    app.register_blueprint(neteng.routes, url_prefix='/neteng')

    from inventory_provider.routes import state_checker
    app.register_blueprint(state_checker.routes, url_prefix='/state-checker')

    from inventory_provider.routes import map
    app.register_blueprint(map.routes, url_prefix='/map')

    if app.config.get('ENABLE_TESTING_ROUTES', False):
        from inventory_provider.routes import testing
        app.register_blueprint(testing.routes, url_prefix='/testing')
        logging.warning('DANGER!!! testing routes enabled')

    logging.info('Inventory Provider Flask app initialized')

    return app