"""Make a single-user app based on the environment:

- $JUPYTERHUB_SINGLEUSER_APP, the base Application class, to be wrapped in JupyterHub authentication.
  default: jupyter_server.serverapp.ServerApp

.. versionchanged:: 2.0

    Default app changed to launch `jupyter labhub`.
    Use JUPYTERHUB_SINGLEUSER_APP='notebook' for the legacy 'classic' notebook server (requires notebook<7).
"""

import os

from traitlets import import_item

from .mixins import make_singleuser_app

JUPYTERHUB_SINGLEUSER_APP = os.environ.get("JUPYTERHUB_SINGLEUSER_APP", "")

# allow shortcut references
_app_shortcuts = {
    "notebook": "notebook.notebookapp.NotebookApp",
    "jupyter-server": "jupyter_server.serverapp.ServerApp",
    "extension": "jupyter_server.serverapp.ServerApp",
}

JUPYTERHUB_SINGLEUSER_APP = _app_shortcuts.get(
    JUPYTERHUB_SINGLEUSER_APP.replace("_", "-"), JUPYTERHUB_SINGLEUSER_APP
)
JUPYVERSE = JUPYTERHUB_SINGLEUSER_APP == "jupyverse"

if JUPYTERHUB_SINGLEUSER_APP:
    if JUPYTERHUB_SINGLEUSER_APP in {"notebook", _app_shortcuts["notebook"]}:
        # better error for notebook v7, which uses jupyter-server
        # when the legacy notebook server is requested
        try:
            from notebook import __version__
        except ImportError:
            # will raise later
            pass
        else:
            # check if this failed because of notebook v7
            _notebook_major_version = int(__version__.split(".", 1)[0])
            if _notebook_major_version >= 7:
                raise ImportError(
                    f"JUPYTERHUB_SINGLEUSER_APP={JUPYTERHUB_SINGLEUSER_APP} is not valid with notebook>=7 (have notebook=={__version__}).\n"
                    f"Leave $JUPYTERHUB_SINGLEUSER_APP unspecified (or use the default JUPYTERHUB_SINGLEUSER_APP=jupyter-server), "
                    'and set `c.Spawner.default_url = "/tree"` to make notebook v7 the default UI.'
                )
    App = None if JUPYVERSE else import_item(JUPYTERHUB_SINGLEUSER_APP)
else:
    App = None
    _import_error = None
    for JUPYTERHUB_SINGLEUSER_APP in (
        "jupyter_server.serverapp.ServerApp",
        "notebook.notebookapp.NotebookApp",
    ):
        try:
            App = import_item(JUPYTERHUB_SINGLEUSER_APP)
        except ImportError as e:
            if _import_error is None:
                _import_error = e
            continue
        else:
            break
    if App is None:
        raise _import_error


if App is None:
    SingleUserNotebookApp = None
else:
    SingleUserNotebookApp = make_singleuser_app(App)


def main():
    """Launch a jupyterhub single-user server"""
    if not os.environ.get("JUPYTERHUB_SINGLEUSER_APP"):
        # app not specified, launch jupyter-labhub by default,
        # if jupyterlab is recent enough (3.1).
        # This is a minimally extended ServerApp that does:
        # 1. ensure lab extension is enabled, and
        # 2. set default URL to `/lab`
        import re

        _version_pat = re.compile(r"(\d+)\.(\d+)")
        try:
            import jupyterlab
            from jupyterlab.labhubapp import SingleUserLabApp

            m = _version_pat.match(jupyterlab.__version__)
        except Exception:
            m = None

        if m is not None:
            version_tuple = tuple(int(v) for v in m.groups())
            if version_tuple >= (3, 1):
                return SingleUserLabApp.launch_instance()

    if JUPYVERSE:
        from fps_auth_jupyterhub import launch

        return launch()

    return SingleUserNotebookApp.launch_instance()
