import time
from typing import Sequence

from clarabot_nano_common.utility.path.resolve import resolve_path
from clarabot_nano_common.utility.serialize import msgpack_dumps

from clarabot_nano.common.core.message import MSG_TYPE_REQUEST_INDEXER_LAST_WORK, MSG_TYPE_CONTROL_INDEXER_WORK
from clarabot_nano.core.process import CoreProcess
from clarabot_nano.core.spawn.tight import TightlyControlledSpawn


class DebugTestCoreProcess(CoreProcess):
    """
    Dump the new configuration into a file so the  testing framework can ensure consistency between processes.
    """

    def __init__(self, config, headless):
        self._last_indexer_work = time.perf_counter()
        CoreProcess.__init__(self, config, headless)
        self._request_handler_map[MSG_TYPE_REQUEST_INDEXER_LAST_WORK] = self._handle_indexer_last_work

    def _apply_and_broadcast_config(self):
        self._write_dbg_config()
        CoreProcess._apply_and_broadcast_config(self)

    def _write_dbg_config(self):
        config_dir = resolve_path(self._config.local["config_dir"], strict=True)
        dbg_config = config_dir / "dbg-config.mpk"
        with dbg_config.open("wb") as f:
            f.write(self._config.serialize())

    def _route_message_to_control(self, instance: TightlyControlledSpawn, routed_message: Sequence[bytes]):
        if routed_message[3] == MSG_TYPE_CONTROL_INDEXER_WORK:
            self._last_indexer_work = time.perf_counter()
        return CoreProcess._route_message_to_control(self, instance, routed_message)

    def _handle_indexer_last_work(self, instance: TightlyControlledSpawn, routed_message: Sequence[bytes]):
        self._reply_to_request(
            routed_message, msgpack_dumps({"elapsed": time.perf_counter() - self._last_indexer_work})
        )
