import { env } from "cloudflare:workers";
import { all } from "../db";
import { accountDb, repoDb } from "../scoped-db";
import { ownerSiteScopes } from "./store";
import { counterTotals } from "../counters";
import { periodEnd, periodOf } from "../metering/record";
import { billingSettings, hardCap, siteCapKey } from "../metering/quota";
import { notifyUsers } from "../notify/deliver";
import { publicUrl } from "../events/emit";
import type { MeterId } from "~/lib/meters";
import { HOSTING_METERS, ROLLUP_DAYS } from "./metering";
import { usageDay } from "./usage";
const DAY_MS = 24 * 60 * 60 * 1000;
/** Per isolate: how often one account's caps or the global ceiling are re-read after counter flushes. */
const ACCOUNT_CHECK_MS = 30_000;
const GLOBAL_CHECK_MS = 60_000;
const FLAG_CACHE_SECONDS = 60;
const GLOBAL_FLAG_TTL_SECONDS = 2 * 24 * 60 * 60;
const MIN_TTL_SECONDS = 60;
const MAX_TRACKED_ACCOUNTS = 1000;
const lastChecked = new Map<string, number>();
let lastGlobalCheck = 0;
type Totals = { requests: number; cpu_ms: number; bytes_out: number };
/** Days of this period a scope may not have folded into usage_periods yet: today and the few before it. */
function recentDays(now: number): string[] {
const period = periodOf(now);
const days = [usageDay(now)];
for (let back = 1; back <= ROLLUP_DAYS; back += 1) {
const day = usageDay(now - back * DAY_MS);
if (!day.startsWith(period)) break;
days.push(day);
}
return days;
}
/** Counters each scope has but not yet folded (its `site_rollups` says which days it folded). */
async function unrolledTotals(accountId: string, days: string[]) {