import { all, first, run } from "../db";
import { randomId } from "../crypto";
import { billingSettings, commitUsage, hardCap, periodUsage, releaseUsage, reserveUsage } from "../metering/quota";
import type { Reservation } from "../metering/quota";
import { recordUsage } from "../metering/record";
import { planAllowsEditorContainers } from "~/lib/plans";
export const EDITOR_INSTANCE_TYPE = "standard-1";
export const EDITOR_METER = "compute.editor";
const MAX_OPEN_SESSIONS = 20;
const HOUR_MS = 60 * 60 * 1000;
const SECOND_MS = 1000;
const MINUTE_S = 60;
export type ContainerUsage = {
/** Seconds committed this month plus the elapsed time of sessions still running. */
usedSeconds: number;
includedSeconds: number;
hardCapSeconds: number | null;
/** False on plans with no editor allowance and a zero hard cap (free tier without a spending limit). */
allowed: boolean;
};
export const CONTAINERS_PAID_ONLY = "Containers are available on paid plans";
/** The account's editor-container usage this month against its plan, for status bars and listings. */
export async function containerUsage(accountId: string): Promise<ContainerUsage> {
const now = Date.now();
const [settings, period, running] = await Promise.all([
billingSettings(accountId),
periodUsage(accountId, EDITOR_METER),
all<{ started_at: number }>(
"SELECT started_at FROM editor_container_sessions WHERE account_id = ? AND stopped_at IS NULL",
accountId,
),
]);
const elapsed = running.reduce((sum, row) => sum + (now - row.started_at) / SECOND_MS, 0);
const includedSeconds = settings.plan.included[EDITOR_METER] ?? 0;
const hardCapSeconds = hardCap(settings, EDITOR_METER);
return {