namespace BlueLaminate.Scraper.CsFloat;
///
/// Rate-limit state parsed from a CSFloat API response's headers. The official
/// docs don't pin down the exact header names, so this is populated generically
/// (any header whose name contains "ratelimit"/"rate-limit", plus "retry-after")
/// and keeps the map so the real names surface during the
/// spike. A future catalog sweep uses /
/// to pace requests and avoid 429s.
///
/// Max requests allowed in the current window, if reported.
/// Requests left in the current window, if reported.
/// Raw reset value as sent (epoch seconds or seconds-until — unverified).
/// Seconds to wait, from a Retry-After header (typically on 429).
/// Every rate-limit-related header, verbatim, for inspection.
public sealed record CsFloatRateLimit(
int? Limit,
int? Remaining,
string? Reset,
int? RetryAfter,
IReadOnlyDictionary Raw)
{
public static readonly CsFloatRateLimit None =
new(null, null, null, null, new Dictionary());
/// True when the API reports zero requests remaining.
public bool IsExhausted => Remaining is <= 0;
public override string ToString() =>
Raw.Count == 0
? "rate-limit: (no headers)"
: "rate-limit: " + string.Join(", ", Raw.Select(kv => $"{kv.Key}={kv.Value}"));
}