__all__ = ["Orchestrator"]

import os

from dishka import Provider, make_container

from argenta.app import App
from argenta.di.integration import setup_dishka
from argenta.di.providers import SystemProvider
from argenta.orchestrator.argparser import ArgParser



class Orchestrator:
    def __init__(
        self,
        arg_parser: ArgParser | None = None,
        custom_providers: list[Provider] | None = None,
        auto_inject_handlers: bool = True,
    ):
        """
        Public. An orchestrator and configurator that defines the behavior of an integrated system, one level higher than the App
        :param arg_parser: Cmd argument parser and configurator at startup
        :return: None
        """
        self._arg_parser: ArgParser | None = arg_parser if not os.getenv('RUN_FROM_ARGENTA_RUNNER') else None
        self._custom_providers: list[Provider] = custom_providers or []
        self._auto_inject_handlers: bool = auto_inject_handlers

        if self._arg_parser is not None:
            self._arg_parser._parse_args()  # pyright: ignore[reportPrivateUsage]

    def run_repl(self, app: App) -> None:
        """
        Public. Starting the user input processing cycle
        :param app: a running application
        :return: None
        """
        container = make_container(
            SystemProvider(), *self._custom_providers, context={ArgParser: self._arg_parser}
        )
        setup_dishka(app, container, auto_inject=self._auto_inject_handlers)

        app._run_repl()  # pyright: ignore[reportPrivateUsage]
