import hashlib
from contextlib import AbstractAsyncContextManager
from typing import List

from maps_adv.export.lib.core.cache import pickle_cache


class PointsCacheClient:
    def __init__(self, points_client: AbstractAsyncContextManager, folder: str):
        self._client = points_client
        self._cache_folder = folder

    @classmethod
    def _hash(cls, polygons: List[List[dict]], points_version: int) -> str:
        hash_sum = hashlib.sha256()
        hash_sum.update(str(points_version).encode())
        for polygon in polygons:
            for point in polygon:
                for key, value in sorted(point.items()):
                    hash_sum.update(str(key).encode())
                    hash_sum.update(str(value).encode())
        return hash_sum.hexdigest()

    async def __call__(self, polygons: List[List[dict]], points_version: int):
        async with self._client as client:
            return await client(polygons, points_version)

    async def __aenter__(self):
        return pickle_cache("points", self, self._hash, self._cache_folder)

    async def __aexit__(self, exc_type, exc_val, exc_tb):
        pass
