"""Serving what an administrator customised.

Both routes here are deliberately **unauthenticated**, and for the same reason
the manifest and the offline page are: the sign-in page needs the logo before
anybody has signed in, and a browser fetches a stylesheet and a launcher icon
outside any page's session.

What that exposes is a file an administrator uploaded on purpose to be shown to
everybody, under a random filename, in a format that cannot execute in an
`<img>` — `services/uploads.py:ALLOWED_TYPES` is what makes the last part true,
and it is why SVG is not in it.
"""

from __future__ import annotations

from fastapi import APIRouter, HTTPException, Response, status
from fastapi.responses import FileResponse

from lembas.services import branding as branding_service
from lembas.services import uploads

router = APIRouter(tags=["branding"])


@router.get("/branding.css", include_in_schema=False)
async def branding_css() -> Response:
    """The custom themes and the custom CSS.

    A route rather than an inline `<style>` in `base.html`, which is a security
    property before it is a caching one: an external stylesheet has no HTML
    context to escape from, so an administrator's CSS cannot become markup
    however it is written. Inline, the same text would be one `</style>` away
    from being a script on every page.

    Cached hard and busted by a query string. `base.html` links this with
    `?v={{ brand.revision }}`, a hash of everything below, so the URL changes
    exactly when the stylesheet does. Without that the browser's cache is what
    decides when a rebrand takes effect, which is a save that looks like it
    worked and did nothing.
    """
    brand = branding_service.snapshot()
    return Response(
        branding_service.stylesheet(brand),
        media_type="text/css",
        headers={"Cache-Control": "public, max-age=604800"},
    )


@router.get("/branding/{filename}", include_in_schema=False)
async def branding_asset(filename: str) -> Response:
    """A logo, a favicon, or a launcher icon derived from one."""
    path = uploads.branding_image_path(filename)
    if path is None:
        raise HTTPException(status.HTTP_404_NOT_FOUND, "No such file.")
    return FileResponse(
        path,
        media_type=uploads.media_type_for(filename),
        # Public, unlike a model avatar: this is served to somebody who is not
        # signed in, so there is nothing private to keep out of a shared cache.
        # Names are random, so a replacement is a new URL.
        headers={
            "Cache-Control": "public, max-age=604800",
            "X-Content-Type-Options": "nosniff",
        },
    )
