import { first, run } from "../db";
import { accountDb } from "../scoped-db";
const DAY_MS = 86_400_000;
const ISO_DATE_LENGTH = 10;
/**
* Mirrors the usage-metering `UsageInput` for meter `ops.integration_deliveries` (one unit per outbound
* delivery, keyed `integration:<deliveryId>` so retries never double-count). Once roadmap/metering lands the
* body becomes `recordUsageSoon(null, { accountId: ownerId, repoId, meter: "ops.integration_deliveries",
* quantity: 1, attributes: { kind, ok, bytes }, idempotencyKey })`. Until then it sums into
* `integration_usage_daily`, which billing does not read.
*/
export type OutboundUsage = {
ownerId: string;
repoId: string | null;
kind: string;
ok: boolean;
bytes: number;
deliveryId: string;
};
export async function recordOutboundDelivery(usage: OutboundUsage, now = Date.now()): Promise<void> {
const day = new Date(Math.floor(now / DAY_MS) * DAY_MS).toISOString().slice(0, ISO_DATE_LENGTH);
try {
const claimed = await run(
"INSERT OR IGNORE INTO integration_usage_keys (key, created_at) VALUES (?, ?)",
`integration:${usage.deliveryId}`,
now,
);
if (!claimed.meta.changes) return;
await accountDb(usage.ownerId).run(
`INSERT INTO integration_usage_daily (owner_id, day, kind, deliveries, failures, bytes) VALUES (?, ?, ?, 1, ?, ?)
ON CONFLICT(owner_id, day, kind) DO UPDATE SET deliveries = deliveries + 1,
failures = failures + excluded.failures, bytes = bytes + excluded.bytes`,
usage.ownerId,
day,
usage.kind,
usage.ok ? 0 : 1,
Math.max(0, Math.floor(usage.bytes)),