/**
 * AUDIT-5 one-shot migration — encrypt existing plaintext MonitorHeader
 * values. Idempotent: rows already in `v1:` form are skipped.
 *
 *   Dry-run: npx tsx scripts/maint/encrypt-monitor-headers.ts
 *   Apply:   npx tsx scripts/maint/encrypt-monitor-headers.ts --apply
 *
 * Safe to run live — monitor-engine.ts decrypts on read via
 * decryptIfNeeded which handles both forms.
 */
import { PrismaClient } from '@prisma/client';
import 'dotenv/config';
import { encrypt, isEncrypted } from '../../src/lib/crypto/secret-vault';

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

async function main(): Promise<void> {
    const rows = await prisma.monitorHeader.findMany({
        select: { id: true, key: true, value: true, monitorId: true },
    });

    const toMigrate = rows.filter((r) => r.value && !isEncrypted(r.value));

    console.log(
        `Scanned ${rows.length} MonitorHeader rows. ` +
        `${toMigrate.length} still in plaintext form.`,
    );

    if (toMigrate.length === 0) {
        console.log('All MonitorHeader values are already encrypted. Done.');
        return;
    }

    // Don't print values themselves — they're secrets.
    const byMonitor = new Map<number, number>();
    for (const r of toMigrate) {
        byMonitor.set(r.monitorId, (byMonitor.get(r.monitorId) ?? 0) + 1);
    }
    console.log('Rows to encrypt by monitorId:');
    for (const [mid, count] of byMonitor) console.log(`  monitorId=${mid}: ${count}`);

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

    let migrated = 0;
    for (const r of toMigrate) {
        await prisma.monitorHeader.update({
            where: { id: r.id },
            data: { value: encrypt(r.value) },
        });
        migrated++;
    }

    console.log(`\nEncrypted ${migrated} MonitorHeader row(s).`);
}

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