/**
 * AUDIT-6 backfill — compute heartbeatTokenHash for existing rows that
 * still rely on the legacy raw heartbeatToken column.
 *
 *   Dry-run: npx tsx scripts/maint/backfill-heartbeat-token-hash.ts
 *   Apply:   npx tsx scripts/maint/backfill-heartbeat-token-hash.ts --apply
 *
 * Safe to run live — the lookup route still falls back to the legacy
 * column for any row whose hash hasn't been populated yet. After this
 * runs, every heartbeat row carries a sha256 in the new column. A
 * follow-up PR drops the heartbeatToken column.
 */
import { PrismaClient } from '@prisma/client';
import 'dotenv/config';
import crypto from 'crypto';

const prisma = new PrismaClient();
const APPLY = process.argv.includes('--apply');

async function main(): Promise<void> {
    const rows = await prisma.monitor.findMany({
        where: {
            type: 'heartbeat',
            heartbeatToken: { not: null },
            heartbeatTokenHash: null,
        },
        select: { id: true, name: true, heartbeatToken: true },
    });

    console.log(
        `Found ${rows.length} heartbeat monitor(s) with raw token but no hash.`,
    );

    if (rows.length === 0) {
        console.log('Nothing to backfill. Done.');
        return;
    }

    for (const r of rows) {
        console.log(`  - id=${r.id} name="${r.name}"`);
    }

    if (!APPLY) {
        console.log('\nDry-run. Re-run with --apply to backfill.');
        return;
    }

    let updated = 0;
    for (const r of rows) {
        if (!r.heartbeatToken) continue;
        const hash = crypto.createHash('sha256').update(r.heartbeatToken).digest('hex');
        await prisma.monitor.update({
            where: { id: r.id },
            data: { heartbeatTokenHash: hash },
        });
        updated++;
    }

    console.log(`\nBackfilled ${updated} heartbeatTokenHash value(s).`);
}

main()
    .catch((e) => {
        console.error('FAILED:', e instanceof Error ? e.message : e);
        process.exit(1);
    })
    .finally(() => prisma.$disconnect());
