from abc import ABCMeta, abstractmethod
from typing import Iterable, TYPE_CHECKING

from sobiraka.models import Page, Volume
from sobiraka.models.config import Config_Web_Search
from sobiraka.processing.html import HeadTag
from sobiraka.utils import AbsolutePath, RelativePath

if TYPE_CHECKING:
    from sobiraka.processing.web import WebBuilder


class SearchIndexer(metaclass=ABCMeta):

    def __init__(self, builder: 'WebBuilder', volume: Volume, index_path: RelativePath | None):
        super().__init__()
        self.builder: WebBuilder = builder
        self.volume: Volume = volume
        self.search_config: Config_Web_Search = volume.config.web.search

        self.index_path_relative: RelativePath = index_path or self.default_index_path(volume)
        self.index_path: AbsolutePath = builder.output / self.index_path_relative

    def __repr__(self):
        return f'<{self.__class__.__name__}: {self.index_path_relative}>'

    @abstractmethod
    def default_index_path(self, volume: Volume) -> RelativePath:
        ...

    async def initialize(self):
        pass

    @abstractmethod
    async def add_page(self, page: Page):
        ...

    async def finalize(self):
        pass

    @abstractmethod
    def results(self) -> set[AbsolutePath]:
        """
        Absolute paths to the files generated by the indexer.
        """

    @abstractmethod
    def head_tags(self) -> Iterable[HeadTag]:
        """
        The tags that must be added to the final HTML for the search to work.
        """
