from contextlib import asynccontextmanager

import aiobotocore.session

from app.config import get_settings
from app.storage.backend import StorageBackend


class S3StorageBackend(StorageBackend):
    def __init__(self) -> None:
        self._settings = get_settings()
        self._session = aiobotocore.session.get_session()

    @asynccontextmanager
    async def _client(self):
        s = self._settings
        async with self._session.create_client(
            "s3",
            region_name=s.s3_region,
            endpoint_url=s.s3_endpoint_url or None,
            aws_access_key_id=s.s3_access_key_id,
            aws_secret_access_key=s.s3_secret_access_key,
        ) as client:
            yield client

    async def put(self, key: str, data: bytes, content_type: str) -> None:
        async with self._client() as client:
            await client.put_object(
                Bucket=self._settings.s3_bucket_name,
                Key=key,
                Body=data,
                ContentType=content_type,
            )

    async def get(self, key: str) -> bytes:
        async with self._client() as client:
            response = await client.get_object(Bucket=self._settings.s3_bucket_name, Key=key)
            return await response["Body"].read()

    async def delete(self, key: str) -> None:
        async with self._client() as client:
            await client.delete_object(Bucket=self._settings.s3_bucket_name, Key=key)
