import argparse
import importlib
import sys
from typing import Optional

from clarabot_nano.common.config.constants import CommonConfigConstants
from clarabot_nano.common.i18n import install_default_l10n
from clarabot_nano.development.spawn.control.tester import ControlApplicationTesterBase, ControlApplicationTester
from clarabot_nano.utility.path.common import normalize_validate_resolve_absolute_path
from clarabot_nano.utility.serialize import msgpack_loads

install_default_l10n()


def startup(tester_module_path: Optional[str], tester_communication_dir: Optional[str]):
    if not tester_module_path:
        with ControlApplicationTesterBase.core_buffer() as core_buffer:
            return ControlApplicationTesterBase(core_buffer).OnRun()
    assert tester_communication_dir, "Communication dir is required for custom control tester"
    tester_communication_dir = normalize_validate_resolve_absolute_path(tester_communication_dir)
    assert tester_communication_dir.is_dir()
    module, _, cls_name = tester_module_path.rpartition(":")
    m = importlib.import_module(module)
    cls = getattr(m, cls_name)
    assert issubclass(cls, ControlApplicationTester), f"{cls}\n{cls.__mro__}\n{m}\n{dir(m)}"
    try:
        init_args = msgpack_loads((tester_communication_dir / "init_args").read_bytes())
    except FileNotFoundError:
        init_args = {}
    init_args["tester_communication_dir"] = tester_communication_dir
    with cls.core_buffer() as core_buffer:
        return cls(core_buffer, **init_args).OnRun()


def main():
    CommonConfigConstants.DEVELOPMENT = True
    parser = argparse.ArgumentParser("Clarabot Nano - Test Control process")
    parser.add_argument("--tester_module_path")
    parser.add_argument("--tester_communication_dir")
    args = parser.parse_args()
    sys.exit(startup(args.tester_module_path, args.tester_communication_dir))


if __name__ == "__main__":
    main()
