# scraper2_hj3415/app/nfs/adapters/out/sinks/nfs_memory_sink.py
from __future__ import annotations

from collections.abc import Iterable

from contracts_hj3415.common.envelope import NfsEnvelopeDTO
from db2_hj3415.common.types import MongoDoc
from db2_hj3415.nfs import mappers
from db2_hj3415.nfs.domain import NfsLatestDoc
from scraper2_hj3415.app.nfs.adapters.out.sinks.store import InMemoryStore
from scraper2_hj3415.app.nfs.ports.sinks.nfs_sink_port import NfsSinkPort


class NfsMemorySink(NfsSinkPort):
    _store: InMemoryStore[MongoDoc]

    def __init__(self, store: InMemoryStore[MongoDoc]):
        self._store = store

    async def write(self, env: NfsEnvelopeDTO) -> None:
        code = env.get("key")
        endpoint = env["payload"]["meta"].get("endpoint")
        doc = mappers.envelope_to_latest_doc(env)
        await self._store.put(endpoint, code, doc)

    async def write_many(self, envs: Iterable[NfsEnvelopeDTO]) -> None:
        out: list[tuple[str, NfsLatestDoc]] = []
        ep_set: set[str] = set()
        for env in envs:
            code = env.get("key")
            endpoint = env["payload"]["meta"].get("endpoint")
            doc = mappers.envelope_to_latest_doc(env)
            out.append((code, doc))
            ep_set.add(endpoint)

        if len(ep_set) != 1:
            raise ValueError(f"multiple endpoints found: {ep_set}")

        ep = next(iter(ep_set))

        await self._store.put_many(ep, out)
