/**
 * CLI script to decrypt FIEL credentials from filesystem backup.
 * Usage: FIEL_ENCRYPTION_KEY=<key> npx tsx scripts/decrypt-fiel.ts <RFC>
 *
 * Decrypted files are written to /tmp/horux-fiel-<RFC>/ and auto-deleted after 30 minutes.
 */
import { readFile, writeFile, mkdir, rm } from 'fs/promises';
import { join } from 'path';
import { createDecipheriv, createHash } from 'crypto';

const FIEL_PATH = process.env.FIEL_STORAGE_PATH || '/var/horux/fiel';
const FIEL_KEY = process.env.FIEL_ENCRYPTION_KEY;

const rfc = process.argv[2];
if (!rfc) {
  console.error('Usage: FIEL_ENCRYPTION_KEY=<key> npx tsx scripts/decrypt-fiel.ts <RFC>');
  process.exit(1);
}
if (!FIEL_KEY) {
  console.error('Error: FIEL_ENCRYPTION_KEY environment variable is required');
  process.exit(1);
}

function deriveKey(): Buffer {
  return createHash('sha256').update(FIEL_KEY!).digest();
}

function decryptBuffer(encrypted: Buffer, iv: Buffer, tag: Buffer): Buffer {
  const key = deriveKey();
  const decipher = createDecipheriv('aes-256-gcm', key, iv);
  decipher.setAuthTag(tag);
  return Buffer.concat([decipher.update(encrypted), decipher.final()]);
}

async function main() {
  const fielDir = join(FIEL_PATH, rfc.toUpperCase());
  const outputDir = `/tmp/horux-fiel-${rfc.toUpperCase()}`;

  console.log(`Reading encrypted FIEL from: ${fielDir}`);

  // Read encrypted certificate
  const cerEnc = await readFile(join(fielDir, 'certificate.cer.enc'));
  const cerIv = await readFile(join(fielDir, 'certificate.cer.iv'));
  const cerTag = await readFile(join(fielDir, 'certificate.cer.tag'));

  // Read encrypted private key
  const keyEnc = await readFile(join(fielDir, 'private_key.key.enc'));
  const keyIv = await readFile(join(fielDir, 'private_key.key.iv'));
  const keyTag = await readFile(join(fielDir, 'private_key.key.tag'));

  // Read and decrypt metadata
  const metaEnc = await readFile(join(fielDir, 'metadata.json.enc'));
  const metaIv = await readFile(join(fielDir, 'metadata.json.iv'));
  const metaTag = await readFile(join(fielDir, 'metadata.json.tag'));

  // Decrypt all
  const cerData = decryptBuffer(cerEnc, cerIv, cerTag);
  const keyData = decryptBuffer(keyEnc, keyIv, keyTag);
  const metadata = JSON.parse(decryptBuffer(metaEnc, metaIv, metaTag).toString('utf-8'));

  // Write decrypted files
  await mkdir(outputDir, { recursive: true, mode: 0o700 });
  await writeFile(join(outputDir, 'certificate.cer'), cerData, { mode: 0o600 });
  await writeFile(join(outputDir, 'private_key.key'), keyData, { mode: 0o600 });
  await writeFile(join(outputDir, 'metadata.json'), JSON.stringify(metadata, null, 2), { mode: 0o600 });

  console.log(`\nDecrypted files written to: ${outputDir}`);
  console.log('Metadata:', metadata);
  console.log('\nFiles will be auto-deleted in 30 minutes.');

  // Auto-delete after 30 minutes
  setTimeout(async () => {
    await rm(outputDir, { recursive: true, force: true });
    console.log(`Cleaned up ${outputDir}`);
    process.exit(0);
  }, 30 * 60 * 1000);
}

main().catch((err) => {
  console.error('Failed to decrypt FIEL:', err.message);
  process.exit(1);
});
