"""BaseDirectTubeScraper — kontrakt dla bezpośrednich scraperów tube'ów."""
from __future__ import annotations

import abc
from collections.abc import Iterator

from app.connectors.base import RawScene


class BaseDirectTubeScraper(abc.ABC):
    """Kontrakt direct scrapera. Wszystkie scrapery feedują do
    `Source(name=SCRAPER_SOURCE_NAME)` ("tube-scraper", rename z "pornapp" 2026-06-07)
    żeby dziedziczyć logikę resolvera + idempotent merge per external_id."""

    sitetag: str
    """Stabilny ID tube'a — używany w external_id `f"{sitetag}:{url}"`. Zgodny
    z porn-app sitetag (hqpornercom, sxylandcom, itp.)."""

    @abc.abstractmethod
    def search(
        self,
        query: str,
        *,
        page: int = 1,
        limit: int | None = None,
    ) -> Iterator[RawScene]:
        """Search tube po query (zwykle: nazwa performera). Yield RawScene per wynik."""
        raise NotImplementedError
