"""
This core process implementation adds minimal modifications for debugging to be possible.
"""

import argparse
from pathlib import Path
from typing import List, Type

import psutil
from clarabot_nano_common.common.config.constants import CommonConfigConstants
from clarabot_nano_common.utility.path.resolve import resolve_path

from clarabot_nano.common.spawn.constants import ShortNames
from clarabot_nano.core.spawn.picoture import PicotureSpawn
from clarabot_nano.core.spawn.solr import SolrSpawn
from clarabot_nano.core.spawn.tika import TikaSpawn
from clarabot_nano.development.core.process import DebugTestCoreProcess
from clarabot_nano.development.spawn.common import write_spawn_debug_info


class _TestingPolledSpawnMixin(object):
    CONFIG_DIR: Path = None

    def __init__(self, process_name: str):
        self._process_name = process_name

    def _post_start_spawn(self, p: psutil.Popen):
        super(_TestingPolledSpawnMixin, self)._post_start_spawn(p)
        write_spawn_debug_info(self.CONFIG_DIR, p.pid, self._process_name)


class _TestingSolrSpawn(_TestingPolledSpawnMixin, SolrSpawn):
    def __init__(self, *args):
        _TestingPolledSpawnMixin.__init__(self, ShortNames.SOLR)
        SolrSpawn.__init__(self, *args)


class _TestingTikaSpawn(_TestingPolledSpawnMixin, TikaSpawn):
    def __init__(self, *args):
        _TestingPolledSpawnMixin.__init__(self, ShortNames.TIKA)
        TikaSpawn.__init__(self, *args)


class _TestingPicotureSpawn(_TestingPolledSpawnMixin, PicotureSpawn):
    def __init__(self, *args):
        _TestingPolledSpawnMixin.__init__(self, ShortNames.PICOTURE)
        PicotureSpawn.__init__(self, *args)


class _TestCoreProcess(DebugTestCoreProcess):
    def __init__(self, config, headless):
        DebugTestCoreProcess.__init__(self, config, headless)
        _TestingPolledSpawnMixin.CONFIG_DIR = resolve_path(self._config.local["config_dir"], strict=True)

    def _spawn_general_server_args(self) -> List[str]:
        return ["clarabot_nano.development.spawn.debug", ShortNames.GENERAL_SERVER]

    def _spawn_gateway_args(self) -> List[str]:
        return ["clarabot_nano.development.spawn.debug", ShortNames.GATEWAY]

    def _spawn_indexer_args(self) -> List[str]:
        return ["clarabot_nano.development.spawn.debug", ShortNames.INDEXER]

    def _spawn_control_args(self) -> List[str]:
        return ["clarabot_nano.development.spawn.debug", ShortNames.CONTROL]

    def _spawn_fstx_server_args(self) -> List[str]:
        return ["clarabot_nano.development.spawn.debug", ShortNames.FSTX_SERVER]

    def _spawn_document_server_args(self) -> List[str]:
        return ["clarabot_nano.development.spawn.debug", ShortNames.DOCUMENT_SERVER]

    def _spawn_solr_cls(self) -> Type[SolrSpawn]:
        return _TestingSolrSpawn

    def _spawn_tika_cls(self) -> Type[TikaSpawn]:
        return _TestingTikaSpawn

    def _spawn_picoture_cls(self) -> Type[PicotureSpawn]:
        return _TestingPicotureSpawn


def main():
    CommonConfigConstants.DEVELOPMENT = True
    parser = argparse.ArgumentParser("Clarabot Nano - Testing Core process")
    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.",
    )
    args = parser.parse_args()
    _TestCoreProcess.startup(args.local_config, args.headless, None, None)


if __name__ == "__main__":
    main()
