from typing import IO, Protocol, override

from template_project.application.common.file_storage import FileStorage


class AioBoto3ClientLike(Protocol):
    async def put_object(
        self,
        *,
        Bucket: str,  # noqa: N803
        Key: str,  # noqa: N803
        Body: IO[bytes],  # noqa: N803
    ) -> None: ...


class S3FileStorage(FileStorage):
    __slots__ = (
        "_bucket_name",
        "_client",
    )

    def __init__(
        self,
        client: AioBoto3ClientLike,
        bucket_name: str,
    ) -> None:
        self._client = client
        self._bucket_name = bucket_name

    @override
    async def upload(
        self,
        path: str,
        image: IO[bytes],
    ) -> None:
        await self._client.put_object(
            Bucket=self._bucket_name,
            Key=path,
            Body=image,
        )
