from typing import cast, TYPE_CHECKING
from analogai.deepthink.presentation.interpreters.interpreter_result import InterpreterResult

if TYPE_CHECKING:
    from analogai.deepthink.presentation.factories.interpreters_factory import InterpretersFactory


_NO_RESULT = object()


class InterpreterPipeline:
    def __init__(self, interpreters_factory: "InterpretersFactory"):
        self._interpreters_factory = interpreters_factory
        self._interpreters = None
        self._result_rules = (
            (self._is_false_result, self._return_false),
            (self._has_value_result, self._return_value),
        )

    def _get_interpreters(self):
        if self._interpreters is None:
            self._interpreters = self._interpreters_factory.create_all()
        return self._interpreters

    def _resolve_interpreter_result(self, result):
        for predicate, mapper in self._result_rules:
            if predicate(result):
                return mapper(result)
        return _NO_RESULT

    @staticmethod
    def _is_false_result(result) -> bool:
        return result is False

    @staticmethod
    def _has_value_result(result) -> bool:
        return result is not None

    @staticmethod
    def _return_false(result):
        return False

    @staticmethod
    def _return_value(result):
        return result

    def run(self, parsed_message, user_agent, message_text: str) -> InterpreterResult | None | bool:
        for interpreter in self._get_interpreters():
            result = interpreter.interpret(parsed_message, user_agent, message_text)
            resolved = self._resolve_interpreter_result(result)
            if resolved is not _NO_RESULT:
                return cast(InterpreterResult | bool | None, resolved)
        return None


if __name__ == "__main__":
    from analogai.deepthink.application.value_objects.user_agent import UserAgent
    from analogai.deepthink.presentation.parsers.parsers_factory import build_message_parser
    pipeline = InterpreterPipeline(InterpretersFactory())
    parser = build_message_parser()
    text = [
            "Iphone X has USB-C port",
            "iphone x has usb-c port",
            "John the programmer",
            "Maria, a talented doctor",
            "my boss Sarah the perfectionist",
            "Elon Musk, founder of SpaceX",
            "I mean the programmer",
            "I mean John, the programmer"]
    for t in text:
        parsed_list = parser.parse(t)
        parsed = parsed_list[0] if parsed_list else None
        result = pipeline.run(parsed, UserAgent(user_id="u", agent_id="a", user_authority=1.0), t)
        print(result)
        print("--------------------------------")
