"""Провайдер DB-IP на основе локальных баз dbipcom."""

from __future__ import annotations

from contextlib import AbstractAsyncContextManager, asynccontextmanager
import logging
from pathlib import Path
from typing import Any, AsyncIterator

from ..dbipcom.mmdb_connector import DBIPResolver
from ..iocs import IOCType
from .base import BaseProvider, FeatureValue

logger = logging.getLogger(__name__)


class DBIPProvider(BaseProvider):
    """Провайдер, выполняющий запросы к встроенным базам DB-IP dbipcom."""

    def __init__(self, database_dir: Path | None = None) -> None:
        """Настроить провайдера DB-IP и указать каталог с базами данных."""
        super().__init__("dbip", requires_token=False)
        if database_dir is None:
            database_dir = Path(__file__).resolve().parent.parent / "dbipcom"
        self.database_dir = database_dir

    def get_context(
        self, token: str | None = None
    ) -> AbstractAsyncContextManager[DBIPResolver]:
        """Создать контекст, предоставляющий ``DBIPResolver``."""

        @asynccontextmanager
        async def _resolver() -> AsyncIterator[DBIPResolver]:
            resolver = DBIPResolver(self.database_dir)
            try:
                yield resolver
            finally:
                resolver.close()

        return _resolver()

    async def fetch(self, indicator: IOCType, context: Any) -> Any | bool:
        """Выполнить локальный поиск DB-IP и вернуть исходный результат."""

        if indicator.category != "ip":
            logger.info(
                "DB-IP не поддерживает индикатор %s (%s)",
                indicator.value,
                indicator.category,
            )
            return False

        if not isinstance(context, DBIPResolver):
            logger.info("DB-IP провайдер вызван без активного резолвера")
            return False

        logger.info("Запрашиваем DB-IP для %s", indicator.value)

        try:
            return context.lookup(indicator.value).to_dict()
        except Exception as exc:
            logger.exception(
                "Не удалось получить данные DB-IP для индикатора %s: %s",
                indicator.value,
                exc,
            )
            return False

    def build_features(
        self,
        payload: Any,
        *,
        indicator: IOCType | None = None,
    ) -> dict[str, FeatureValue]:
        """Подготовить фичи для данных DB-IP (заглушка)."""

        indicator_value = getattr(indicator, "value", indicator)
        logger.debug(
            "Строим фичи DB-IP по индикатору %s", indicator_value
        )

        asn_info = payload.get("asn") if isinstance(payload, dict) else None

        return {
            "asn_number": (asn_info or {}).get("number"),
            "asn_organization": (asn_info or {}).get("organization"),
        }
