# SPDX-License-Identifier: AGPL-3.0-or-later
"""Typification of the result items generated by the *engines*, *answerers* and
*plugins*.

.. note::

   We are at the beginning of typing the results.  Further typing will follow,
   but this is a very large task that we will only be able to implement
   gradually.  For more, please read :ref:`result types`.

"""
# pylint: disable=too-few-public-methods


__all__ = [
    "Result",
    "MainResult",
    "KeyValue",
    "EngineResults",
    "AnswerSet",
    "Answer",
    "Translations",
    "WeatherAnswer",
    "Code",
    "Paper",
    "File",
]

import typing as t
import abc

from ._base import Result, MainResult, LegacyResult
from .answer import AnswerSet, Answer, Translations, WeatherAnswer
from .keyvalue import KeyValue
from .code import Code
from .paper import Paper
from .file import File


class ResultList(list[Result | LegacyResult], abc.ABC):
    """Base class of all result lists (abstract)."""

    @t.final
    class types:  # pylint: disable=invalid-name
        """The collection of result types (which have already been
        implemented)."""

        Answer = Answer
        KeyValue = KeyValue
        Code = Code
        Paper = Paper
        File = File
        MainResult = MainResult
        Result = Result
        Translations = Translations
        WeatherAnswer = WeatherAnswer

        # for backward compatibility
        LegacyResult = LegacyResult

    def __init__(self):
        # pylint: disable=useless-parent-delegation
        super().__init__()

    def add(self, result: Result | LegacyResult):
        """Add a :py:`Result` item to the result list."""
        self.append(result)


class EngineResults(ResultList):
    """Result list that should be used by engine developers.  For convenience,
    engine developers don't need to import types / see :py:obj:`ResultList.types`.

    .. code:: python

       from searx.result_types import EngineResults
       ...
       def response(resp) -> EngineResults:
           res = EngineResults()
           ...
           res.add( res.types.Answer(answer="lorem ipsum ..", url="https://example.org") )
           ...
           return res
    """
