/**
 * Data migration: encrypts existing plaintext WireGuard private keys
 * and pre-shared keys in the database.
 *
 * This migration is safe to run multiple times (idempotent):
 * already-encrypted values (prefix "enc:") are skipped.
 *
 * Requires DB_ENCRYPTION_KEY to be set in the environment.
 * If not set, migration logs a warning and exits without modifying data.
 */

import { encrypt } from "../lib/crypto.js";

const migrate_name = "wireguard_encrypt_keys";

export async function up(knex) {
	const key = process.env.DB_ENCRYPTION_KEY;
	if (!key) {
		console.warn(`[${migrate_name}] DB_ENCRYPTION_KEY not set — skipping encryption migration. Keys remain as plaintext.`);
		return;
	}

	console.log(`[${migrate_name}] Encrypting existing WireGuard keys...`);

	// --- wg_interface: encrypt private_key ---
	const ifaces = await knex("wg_interface").select("id", "private_key");
	let ifaceCount = 0;
	for (const iface of ifaces) {
		if (!iface.private_key || iface.private_key.startsWith("enc:")) continue;
		await knex("wg_interface").where("id", iface.id).update({
			private_key: encrypt(iface.private_key),
		});
		ifaceCount++;
	}
	console.log(`[${migrate_name}]   wg_interface: ${ifaceCount} rows encrypted.`);

	// --- wg_client: encrypt private_key + pre_shared_key ---
	const clients = await knex("wg_client").select("id", "private_key", "pre_shared_key");
	let clientCount = 0;
	for (const client of clients) {
		const updates = {};
		if (client.private_key && !client.private_key.startsWith("enc:")) {
			updates.private_key = encrypt(client.private_key);
		}
		if (client.pre_shared_key && !client.pre_shared_key.startsWith("enc:")) {
			updates.pre_shared_key = encrypt(client.pre_shared_key);
		}
		if (Object.keys(updates).length > 0) {
			await knex("wg_client").where("id", client.id).update(updates);
			clientCount++;
		}
	}
	console.log(`[${migrate_name}]   wg_client: ${clientCount} rows encrypted.`);
	console.log(`[${migrate_name}] Done.`);
}

export async function down(knex) {
	// Intentionally a no-op: decrypting back to plaintext would require the key,
	// and rolling back encryption is a security risk.
	console.warn(`[${migrate_name}] down() is a no-op. Keys remain encrypted.`);
}
