import logging
import random
from abc import ABC, abstractmethod
from typing import Any, Dict, List, Optional, Tuple
from typing import TYPE_CHECKING


class Scheduler(ABC):
    """
    This abstract class defines as must be a Scheduler to walk over grammar.
    """

    def __init__(
        self,
        problem_metadata: Optional[Dict[str, Any]] = None,
        batch_size: int = 1,
    ) -> None:
        self._problem_metadata = problem_metadata

        self._batch_size = batch_size
        self._feedback: Optional[dict] = None

    @abstractmethod
    def set_space(self, grammar_tree: "GrammarTree") -> None:
        """
        grammar_tree : GrammarTree
        A `GrammarTree` object representing the space as a grammar tree.

        This setter method assigns a `GrammarTree` object as the space for searching.
        """
        pass  # pragma: no cover

    @property
    @abstractmethod
    def feedback(self) -> Optional[dict]:  # pylint: disable=C0116
        pass  # pragma: no cover

    @feedback.setter
    @abstractmethod
    def feedback(self, value: Optional[dict]) -> None:
        pass  # pragma: no cover

    @abstractmethod
    def get_sequences(self, batch_size: Optional[int] = None) -> List[List[Any]]:
        """
        Get the sequences from the grammar tree.

        Returns:
        -------
        int : The number of sequences in the grammar tree.
        """
        pass  # pragma: no cover

    @property
    def batch_size(self):
        return self._batch_size