import argparse
from typing import List

from clarabot_nano.common.config.constants import CommonConfigConstants
from clarabot_nano.common.i18n import install_default_l10n
from clarabot_nano.common.spawn.constants import ShortNames
from clarabot_nano.core.__main__ import start_core
from clarabot_nano.core.spawner.base import AbstractSpawner
from clarabot_nano.core.spawner.tight import TightPythonSpawner
from clarabot_nano.development.common import load_development_server_config
from clarabot_nano.development.core.process import DebugTestCoreProcess

install_default_l10n()


class _TestCoreProcess(DebugTestCoreProcess):
    def __init__(self, config, headless, development_server_config, indexer_args, control_args):
        self.development_server_config = development_server_config or ""
        self.indexer_args = indexer_args or []
        self.control_args = control_args or []
        DebugTestCoreProcess.__init__(self, config, headless)

    def _spawn_general_server_args(self) -> List[str]:
        return ["clarabot_nano.development.spawn.server.general"]

    def _spawn_gateway_args(self) -> List[str]:
        return ["clarabot_nano.development.spawn.gateway", self.development_server_config]

    def _spawn_indexer_args(self) -> List[str]:
        return ["clarabot_nano.development.spawn.indexer"] + self.indexer_args

    def _spawn_control_args(self) -> List[str]:
        return ["clarabot_nano.development.spawn.control"] + self.control_args

    def _spawn_fstx_server_args(self) -> List[str]:
        return ["clarabot_nano.development.spawn.server.fstx"]

    def _create_spawners(self) -> List[AbstractSpawner]:
        spawners = DebugTestCoreProcess._create_spawners(self)
        spawners.append(
            TightPythonSpawner(
                "nano-debug",
                ["clarabot_nano.development.spawn.debug", ShortNames.DEBUG],
                dispose_callback=self._tight_dispose_callback,
                only_spawn_when_clean=True,
            )
        )
        return spawners


def main():
    CommonConfigConstants.DEVELOPMENT = True
    parser = argparse.ArgumentParser("Clarabot Nano - Testing Core process")
    parser.add_argument("--development_server_config")
    parser.add_argument("--indexer_args", action="append")
    parser.add_argument("--control_args", action="append")
    parser.add_argument(
        "-c",
        "--local_config",
        help="The local configuration file of a Nano instance. "
        "If not provided a default configuration will be used or created under the user's home.",
    )
    parser.add_argument(
        "--headless",
        action="store_true",
        help="Start without graphical interface even if it is available.",
    )
    parser.add_argument(
        "--bootstrap_login",
        action="store_true",
        help="Start a command line utility that handles login or account-change of the instance.",
    )
    parser.add_argument(
        "--bootstrap_config_dir",
        help='Path where configs other than "local.yaml" shall reside for an explicit new instance. '
        'Required if "--local_config" is specified to a new path, ignored otherwise.',
    )
    parser.add_argument(
        "--bootstrap_data_dir",
        help="Path where the data shall be stored for an explicit new instance. "
        'Required if "--local_config" is specified to a new path, ignored otherwise.',
    )
    args = parser.parse_args()
    load_development_server_config(args.development_server_config)
    start_core(args, args.development_server_config, args.indexer_args, args.control_args, cls=_TestCoreProcess)


if __name__ == "__main__":
    main()
