import * as crypto from 'crypto';
import * as fs from 'fs/promises';
import * as path from 'path';
import { createLogger } from '@4runr/shared';
const logger = createLogger('LogEncryption');
let config = {
    enabled: false,
    algorithm: 'aes-256-gcm'
};
export function initLogEncryption(encryptionKey) {
    if (!encryptionKey) {
        config.enabled = false;
        logger.warn('Log encryption disabled - no encryption key provided');
        return;
    }
    try {
        const keyMaterial = Buffer.from(encryptionKey, 'utf-8');
        config.key = crypto.createHash('sha256').update(keyMaterial).digest();
        config.enabled = true;
        logger.info('Log encryption enabled');
    }
    catch (error) {
        logger.error('Failed to initialize log encryption', {
            error: error instanceof Error ? error.message : String(error)
        });
        config.enabled = false;
    }
}
function encryptLogEntry(plaintext) {
    if (!config.enabled || !config.key) {
        return plaintext;
    }
    try {
        const iv = crypto.randomBytes(16);
        const cipher = crypto.createCipheriv(config.algorithm, config.key, iv);
        let encrypted = cipher.update(plaintext, 'utf-8', 'hex');
        encrypted += cipher.final('hex');
        const authTag = cipher.getAuthTag();
        return `${iv.toString('hex')}:${authTag.toString('hex')}:${encrypted}`;
    }
    catch (error) {
        logger.error('Failed to encrypt log entry', {
            error: error instanceof Error ? error.message : String(error)
        });
        return plaintext;
    }
}
export function decryptLogEntry(encrypted) {
    if (!config.enabled || !config.key) {
        return encrypted;
    }
    try {
        const parts = encrypted.split(':');
        if (parts.length !== 3) {
            return encrypted;
        }
        const [ivHex, authTagHex, encryptedHex] = parts;
        if (!ivHex || !authTagHex || !encryptedHex) {
            return encrypted;
        }
        const iv = Buffer.from(ivHex, 'hex');
        const authTag = Buffer.from(authTagHex, 'hex');
        const encryptedData = Buffer.from(encryptedHex, 'hex');
        const decipher = crypto.createDecipheriv(config.algorithm, config.key, iv);
        decipher.setAuthTag(authTag);
        let decrypted = decipher.update(encryptedData, undefined, 'utf-8');
        decrypted += decipher.final('utf-8');
        return decrypted;
    }
    catch (error) {
        logger.error('Failed to decrypt log entry', {
            error: error instanceof Error ? error.message : String(error)
        });
        return encrypted;
    }
}
export async function writeEncryptedLog(filePath, logEntry) {
    try {
        const encrypted = encryptLogEntry(logEntry);
        const dir = path.dirname(filePath);
        await fs.mkdir(dir, { recursive: true });
        await fs.appendFile(filePath, encrypted + '\n', 'utf-8');
    }
    catch (error) {
        logger.error('Failed to write encrypted log', {
            filePath,
            error: error instanceof Error ? error.message : String(error)
        });
        throw error;
    }
}
export async function readEncryptedLog(filePath) {
    try {
        const content = await fs.readFile(filePath, 'utf-8');
        const lines = content.split('\n').filter(line => line.trim());
        return lines.map(line => decryptLogEntry(line));
    }
    catch (error) {
        logger.error('Failed to read encrypted log', {
            filePath,
            error: error instanceof Error ? error.message : String(error)
        });
        throw error;
    }
}
export function createEncryptedLogStream(filePath) {
    let buffer = [];
    let writePromise = null;
    const flush = async () => {
        if (buffer.length === 0)
            return;
        const toWrite = buffer.join('\n') + '\n';
        buffer = [];
        const encrypted = encryptLogEntry(toWrite);
        await fs.appendFile(filePath, encrypted, 'utf-8');
    };
    return {
        write: async (entry) => {
            buffer.push(entry);
            if (buffer.length >= 10) {
                if (writePromise) {
                    await writePromise;
                }
                writePromise = flush();
                await writePromise;
                writePromise = null;
            }
        },
        close: async () => {
            if (writePromise) {
                await writePromise;
            }
            await flush();
        }
    };
}
export function isLogEncryptionEnabled() {
    return config.enabled;
}
//# sourceMappingURL=log-encryption.js.map