/**
 * One-off migration: encrypt any plaintext NotificationChannel.config rows.
 *
 * The encryption-at-rest rollout is backwards-compatible — readers handle
 * both v1: envelopes and legacy plaintext. This script flips every
 * legacy row over to v1 so that nothing remains plaintext.
 *
 * Idempotent: rows already starting with `v1:` are skipped.
 *
 * Pre-requisites:
 *   - CHANNEL_ENCRYPTION_KEY env var set to a 32-byte base64 value:
 *       openssl rand -base64 32
 *   - Database backed up (recommended for any encryption migration).
 *
 * Run with:
 *   npx tsx scripts/encrypt-existing-channels.ts
 */

import { PrismaClient } from '@prisma/client';
import { encrypt, isEncrypted } from '../src/lib/crypto/secret-vault';

const prisma = new PrismaClient();

async function main() {
    if (!process.env.CHANNEL_ENCRYPTION_KEY) {
        console.error('[migrate] CHANNEL_ENCRYPTION_KEY is not set. Aborting.');
        process.exit(1);
    }

    const all = await prisma.notificationChannel.findMany({
        select: { id: true, type: true, config: true, deletedAt: true },
    });

    let skipped = 0;
    let encrypted = 0;
    let badRows = 0;

    for (const row of all) {
        if (row.deletedAt !== null) {
            skipped++;
            continue;
        }
        const config = row.config ?? '';
        if (!config) {
            skipped++;
            continue;
        }
        if (isEncrypted(config)) {
            skipped++;
            continue;
        }
        // Sanity: every channel.config should be a JSON object string. Skip
        // anything that doesn't parse — surface to operator for manual triage.
        try {
            JSON.parse(config);
        } catch {
            console.warn(`[migrate] row id=${row.id} (type=${row.type}) has unparseable config — skipping (not encrypting garbage)`);
            badRows++;
            continue;
        }

        const envelope = encrypt(config);
        await prisma.notificationChannel.update({
            where: { id: row.id },
            data: { config: envelope },
        });
        encrypted++;
        console.log(`[migrate] id=${row.id.toString().padStart(4)} type=${row.type.padEnd(10)} encrypted`);
    }

    console.log('');
    console.log(`[migrate] DONE. encrypted=${encrypted}  skipped=${skipped}  bad=${badRows}`);
}

main()
    .catch((e) => { console.error('[migrate] FAILED:', e); process.exit(1); })
    .finally(() => prisma.$disconnect());
