import os
from enum import Enum
from typing import Any, List

import axipy
from axipy.cpp_app import ShadowApplication
from axipy.gui import gui_instance
from axipy.settings import AxiomaLanguage
from PySide2.QtWidgets import QApplication

__all__: List[str] = [
    "init_axioma",
    "AxiomaInitLogLevel",
]


class AxiomaInitLogLevel(str, Enum):
    """Уровень логирования Аксиомы при запуске из python."""

    maximum = "0"
    """Максимальный."""
    high = "1"
    """Высокий."""
    medium = "2"
    """Средний."""
    minimum = "3"
    """Минимальный."""
    disabled = "-1"
    """Логирование отключено."""


def init_axioma(
    *,
    log_level: AxiomaInitLogLevel = AxiomaInitLogLevel.medium,
    language: AxiomaLanguage = AxiomaLanguage.ru,
    load_python_plugins: bool = False,
) -> QApplication:
    """
    Инициализирует ядро ГИС Аксиома.

    Args:
        log_level: Уровень логирования.
        language: Язык Аксиомы.
        load_python_plugins: Загружать плагины.

    Returns:
        Приложение Qt5 c очередью событий (event-loop).

    Пример::

        from axipy import init_axioma, mainwindow, AxiomaInitLogLevel

        app = init_axioma(log_level=AxiomaInitLogLevel.disabled)
        mainwindow.show()
        app.exec_()  # запускает обработку очереди событий
    """

    def set_environ(environ_name: str, arg: Any) -> None:
        if os.environ.get(environ_name) is None:
            os.environ[environ_name] = arg

    set_environ("AXIOMA_LOG_LEVEL", log_level.value)
    set_environ("AXIOMA_LANGUAGE", language)
    set_environ("AXIOMA_MISS_LOAD_PYTHON_PLUGINS", str(not load_python_plugins))

    if gui_instance._is_initialized():
        app = QApplication.instance()
    else:
        home_dir = os.environ["AXIOMA_HOME"]
        os.chdir(home_dir)
        app = QApplication()
        ShadowApplication.initialize(app)
        gui_instance._initialize()

    return app


def _apply_deprecated() -> None:
    # Using getattr to hide deprecated objects from axipy namespace on IDE inspections
    getattr(__all__, "extend")(
        (
            "io",
            "data",
            "AxiomaInitLanguage",
        )
    )

    globals().update(
        io=axipy.provider_manager,
        data=axipy.provider_manager,
        AxiomaInitLanguage=AxiomaLanguage,
    )


_apply_deprecated()
