# isort: off
from {{application.module_name}}._version import __version__
from {{application.module_name}}._app_type import AppType
# isort: on

{% if module.database %}
from typing import Any, cast
from sqlalchemy import MetaData

from sqlalchemy.orm import Session
from {{application.module_name}}.modules.database import Base
{% endif %}

def create_app():
    application_configs = []
    application_modules = []

    {% if 'database' in module %}
    from Ligare.database.config import DatabaseConfig
    from Ligare.database.dependency_injection import ScopedSessionModule
    application_configs.append(DatabaseConfig)
    application_modules.append(ScopedSessionModule())
    {% endif %}

    # fmt: off
    from Ligare.web.application import App
    result = App[AppType].create(
        config_filename="{{application.module_name}}/config.toml",
        application_configs=application_configs,
        application_modules=application_modules
    )
    # fmt: on

    {% if module.database %}
    # TODO For now, create the database and tables
    # when the application starts. This behavior
    # will be removed when Alembic is integrated.
    session = result.app_injector.flask_injector.injector.get(Session)
    cast(MetaData, Base.metadata).create_all(session.bind)

    {#
        # TODO ideally this would use @inject w/ session: Session,
        but something is preventing it from running or
        sending in the dependencies to remove_db.
        For now, just resolve it directly.
    #}
    @result.flask_app.teardown_request
    def remove_db(exception: Any):
        session = result.app_injector.flask_injector.injector.get(Session)
        session.rollback()
    {% endif %}

    return result
