package wang.yaojia.webterm.api.routes

/**
 * Client-side FCM registration-token validator (validate at the boundary, plan §4). Deliberately
 * LOOSE, per plan §4.5: non-empty, bounded length, `base64url` charset plus `:` — the FCM token
 * format/length is undocumented and changes, so a strict length regex risks rejecting valid tokens.
 *
 * Unlike iOS's APNs hex rule, FCM tokens are case-sensitive → NOT lowercased. [normalize] returns
 * the token unchanged when valid, or `null` (→ `ApiClientError.InvalidFcmToken` before any I/O).
 */
internal object FcmTokenRule {
    /** Generous headroom bound; real tokens are ~150–250 chars but the ceiling is undocumented. */
    private const val MAX_LENGTH = 4096

    /** base64url alphabet (`A–Z a–z 0–9 - _`) plus the `:` that appears in FCM tokens. */
    private val ALLOWED: Set<Char> =
        (('A'..'Z') + ('a'..'z') + ('0'..'9') + listOf('-', '_', ':')).toSet()

    fun normalize(raw: String): String? {
        if (raw.isEmpty() || raw.length > MAX_LENGTH) return null
        if (!raw.all { it in ALLOWED }) return null
        return raw
    }
}
