import json
import ssl
from pathlib import Path

import httpx
from tenacity import (
    retry,
    retry_if_exception_type,
    stop_after_attempt,
    wait_exponential,
)

from harbor.auth.client import create_authenticated_client, reset_client
from harbor.storage.base import BaseStorage

BUCKET = "packages"
UPLOAD_MAX_ATTEMPTS = 4
RETRYABLE_UPLOAD_EXCEPTIONS = (httpx.RequestError, ssl.SSLError, json.JSONDecodeError)


class SupabaseStorage(BaseStorage):
    @retry(
        retry=retry_if_exception_type(RETRYABLE_UPLOAD_EXCEPTIONS),
        stop=stop_after_attempt(UPLOAD_MAX_ATTEMPTS),
        wait=wait_exponential(multiplier=0.5, min=0.5, max=4.0),
        before_sleep=lambda _: reset_client(),
        reraise=True,
    )
    async def upload_file(self, file_path: Path, remote_path: str) -> None:
        client = await create_authenticated_client()
        data = file_path.read_bytes()
        await client.storage.from_(BUCKET).upload(remote_path, data)

    async def download_file(self, remote_path: str, file_path: Path) -> None:
        client = await create_authenticated_client()
        data = await client.storage.from_(BUCKET).download(remote_path)
        file_path.parent.mkdir(parents=True, exist_ok=True)
        file_path.write_bytes(data)
