var fs = require('fs');
var crypto = require('crypto');

exports.readFileSync = function(enc_method, enc_passphrase, filename)
{
	// read entire file into memory
	var fileData = fs.readFileSync(filename, 'binary');
	if (fileData.length < 32)
		throw new Error("Crypted file " + filename + " truncated");

	// separate into data, hmac parts
	var fileCrypted = fileData.slice(0, -32);
	var fileHmac = fileData.slice(-32);

	// generate and verify HMAC
	var hmac = crypto.createHmac('sha256', enc_passphrase);
	hmac.update(fileCrypted);
	var digest = hmac.digest('binary');

	if (digest.toString() != fileHmac.toString())
		throw new Error("Crypted file " + filename + " failed HMAC checksum verification");

	// decrypt to plaintext
	var decipher = crypto.createDecipher(enc_method, enc_passphrase);
	var dec = decipher.update(fileCrypted, 'binary', 'binary');
	dec += decipher.final('binary');
	return dec;
};

exports.readJFileSync = function(enc_method, enc_passphrase, filename)
{
	var raw = this.readFileSync(enc_method, enc_passphrase, filename);
	return JSON.parse(raw);
};

exports.writeFileSync = function(enc_method, enc_passphrase, filename, data)
{
	// encrypt to ciphertext
	var cipher = crypto.createCipher(enc_method, enc_passphrase);
	var crypted = cipher.update(data, 'binary', 'binary');
	crypted += cipher.final('binary');

	// compute HMAC
	var hmac = crypto.createHmac('sha256', enc_passphrase);
	hmac.update(crypted);
	var digest = hmac.digest('binary');

	fs.writeFileSync(filename, crypted + digest, 'binary');

	return true;
};

exports.writeJFileSync = function(enc_method, enc_passphrase, filename, obj)
{
	var raw = JSON.stringify(obj);
	return this.writeFileSync(enc_method, enc_passphrase, filename, raw);
};