"""What is running here, and getting to what is not.

Read `services/updates.py` first — the reason the button writes a file rather
than doing the work is there, and it is the whole design.
"""

from __future__ import annotations

import logging

from fastapi import APIRouter, Request, Response, status
from fastapi.responses import RedirectResponse

from lembas.api.deps import AdminUser, Db
from lembas.services import updates as updates_service
from lembas.web.templating import render

log = logging.getLogger(__name__)

router = APIRouter(prefix="/admin/updates", tags=["admin-updates"])


def _page(request: Request, state, saved: str = "") -> Response:
    return render(
        request,
        "admin/updates.html",
        {
            "state": state,
            "command": updates_service.manual_command(),
            "saved": saved,
        },
    )


@router.get("")
async def updates_page(request: Request, db: Db, user: AdminUser, saved: str = ""):
    """No network on a page load.

    `read(fetch=False)` compares against whatever the last fetch left behind, so
    opening this is a few git reads off the local disk. A page that reached the
    remote every time it was rendered would be one somebody stops opening.
    """
    return _page(request, updates_service.read(), saved)


@router.post("/check")
async def check(request: Request, db: Db, user: AdminUser) -> Response:
    """Ask the remote what is there. The one place this touches the network."""
    state = updates_service.read(fetch=True)
    log.info("%s checked for updates", user.email)
    return _page(request, state)


@router.post("/apply")
async def apply(db: Db, user: AdminUser) -> Response:
    """Write the request the helper is watching for.

    Refused when the helper is not installed rather than written and left to sit
    there: a file nothing is watching is a button that reports success and does
    nothing, which is the failure this codebase keeps cataloguing.
    """
    if not updates_service.helper_installed():
        return RedirectResponse(
            "/admin/updates?saved=The+update+helper+is+not+installed+on+this+host.",
            status_code=status.HTTP_303_SEE_OTHER,
        )
    problem = updates_service.request_update(user.email)
    message = problem or "Update requested. The service will restart in a moment."
    return RedirectResponse(
        f"/admin/updates?saved={message.replace(' ', '+')}",
        status_code=status.HTTP_303_SEE_OTHER,
    )


@router.post("/cancel")
async def cancel(db: Db, user: AdminUser) -> Response:
    updates_service.clear_request()
    return RedirectResponse(
        "/admin/updates?saved=Request+withdrawn.", status_code=status.HTTP_303_SEE_OTHER
    )
