"""Per-project Cloud service token for generated-app BFFs and Edge Functions."""
from __future__ import annotations

import secrets
from uuid import UUID

from src.core.security.encryption import decrypt_value, encrypt_value


async def _push_function_token(cloud, project_id: UUID, token: str) -> None:
    try:
        await cloud.push_function_token(project_id=str(project_id), token=token)
    except Exception as exc:
        status = getattr(getattr(exc, "response", None), "status_code", None)
        if status != 404:
            raise


async def ensure_project_cloud_service_token(
    tokens,
    cloud,
    project_id: UUID,
    *,
    always_push: bool = False,
) -> str:
    """Return the project-scoped Cloud token, creating and pushing it if needed.

    This is CLOUD_SERVICE_TOKEN on generated apps. It is not the platform-wide
    INTERNAL_CONTROL_TOKEN; Cloud only accepts it for this project.
    """
    row = await tokens.get(project_id)
    if row:
        token = decrypt_value(row.token_enc)
        if always_push:
            await _push_function_token(cloud, project_id, token)
        return token
    token = secrets.token_urlsafe(32)
    await tokens.create(project_id, encrypt_value(token))
    await _push_function_token(cloud, project_id, token)
    return token
