from typing import Generic, TypeVar, Callable


T = TypeVar('T')


class ValueStore(Generic[T]):
    """
    A simple class that can store a value.
    This is useful when an in-process actor needs to submit something.

    For example, consider a local
    (local agent loop, not necessarily local LLM)
    agent that is given a task to fix a bug.
    After it finishes the task, it needs to submit the result somewhere,
    be it a filepath, a patch, or something else.

    With this helper class, you can then create a tool for the agent,
    which, when called, sets the value.
    Then, when collecting the final results for the rollout,
    you can read the value from this value store to retrieve the data submitted by the agent.
    """

    def __init__(self, on_value_set: Callable[[T], None] | None):
        """
        Constructor.
        :param on_value_set: Called when a value is set.
        """
        self._on_value_set = on_value_set
        self._value: T | None = None

    @property
    def value(self) -> T | None:
        """
        Gets the data.
        :return:
        """
        return self._value

    @value.setter
    def value(self, val: T) -> None:
        """
        Sets the data.
        :param val:
        :return:
        """

        self._value = val

        if self._on_value_set is not None:
            self._on_value_set(val)
