/**
 * Where a stream left off, as `EventSource` carries it.
 *
 * ## Why the cursor is a notification id and not a time
 *
 * SSE resumption is the whole of `Last-Event-ID`: the browser remembers the
 * last `id:` it was sent and hands it back on the reconnect it makes by itself.
 * So whatever goes in that field has to answer "what came after this" exactly,
 * across a wifi drop, weeks later, from a header the client controls.
 *
 * A timestamp cannot. `created_at` is a `timestamptz` with microsecond
 * resolution and a JavaScript `Date` holds milliseconds, so a cursor that
 * travelled through one would name an instant slightly *before* the row it was
 * taken from, and that row would be sent again on every reconnect. The id
 * carries no precision of its own to lose: the ordering is read back out of the
 * row itself, in SQL, where the microseconds still are.
 *
 * ## Why it is safe to take from the header
 *
 * The id names a row, and every query it feeds is also scoped to the person
 * asking. A header naming somebody else's notification moves the asker's own
 * window and reveals nothing; a header naming nothing at all matches nothing,
 * which is a stream that replays nothing. The only thing that has to be
 * refused here is a value that is not a UUID, because that reaches the database
 * as a cast error rather than as a question.
 *
 * Pure, with nothing under it: the route handler reads the header and the
 * service builds the query, and neither should own the shape.
 */

const UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i

/**
 * The header, or nothing.
 *
 * Null means "no usable resume point", which is not the same as "from the
 * beginning": a stream that cannot tell where it was starts from now, and the
 * caller is what decides that. Garbage arrives here as null for the same
 * reason, so a corrupted header costs a client nothing beyond the replay it
 * could not have had anyway.
 */
export function readCursor(raw: string | null | undefined): string | null {
  if (typeof raw !== "string") return null
  const value = raw.trim()
  return UUID.test(value) ? value.toLowerCase() : null
}
