import re
from abc import ABC, abstractmethod


class Preprocessor(ABC):
    """
    Abstract base class for text preprocessors.

    Subclass this and implement `preprocess` to define custom text cleaning
    logic before passing text to the chunking model.

    The model expects plain text without newlines or other control characters —
    ideally sentences separated by single spaces.
    """

    @abstractmethod
    def preprocess(self, text: str) -> str:
        """
        Clean and normalize input text.

        Args:
            text: Raw input text.

        Returns:
            Cleaned text ready for the chunking model.
        """
        ...


class DefaultPreprocessor(Preprocessor):
    """
    Normalizes text for the chunking model.

    Replaces all newlines, tabs and carriage returns with spaces,
    then collapses multiple consecutive spaces into one.
    """

    def preprocess(self, text: str) -> str:
        text = re.sub(r"[\n\r\t]+", " ", text)
        text = re.sub(r" +", " ", text)
        return text.strip()
