//! This module contains constant values, functions and types that are used around the crate.

// DO NOT EDIT THIS FILE. IF THESE CONSTANTS CHANGE, THINGS CAN (AND PROBABLY WILL) BREAK

// Stream functionality temporarily disabled due to aead::stream removal in 0.6.0-rc.2
// use aead::stream::{Nonce, StreamLE31};
use chacha20poly1305::XNonce;
// XChaCha20Poly1305 temporarily unused due to stream functionality being disabled
// use chacha20poly1305::XChaCha20Poly1305;

pub type OneShotNonce = XNonce;
// Temporary placeholder for StreamNonce until stream functionality is reimplemented
pub type StreamNonce = [u8; 20];
pub use chacha20poly1305::Tag;

#[derive(Debug, Clone)]
pub struct EncryptedBlock {
	pub nonce: OneShotNonce,
	pub cipher_text: Vec<u8>,
}

pub struct EncryptedBlockRef<'e> {
	pub nonce: &'e OneShotNonce,
	pub cipher_text: &'e [u8],
}

impl<'e> From<&'e [u8]> for EncryptedBlockRef<'e> {
	fn from(cipher_text: &'e [u8]) -> Self {
		let (nonce, cipher_text) = cipher_text.split_at(size_of::<OneShotNonce>());

		Self {
			nonce: nonce.try_into().expect("we split the correct amount"),
			cipher_text,
		}
	}
}

impl EncryptedBlock {
	/// The block size used for STREAM encryption/decryption. This size seems to offer
	/// the best performance compared to alternatives.
	///
	/// The file size gain is 24 bytes per 1MiB due to nonce of XChaCha20-Poly1305
	pub const PLAIN_TEXT_SIZE: usize = 1_048_576;

	/// The size of a encrypted block with its tag.
	pub const CIPHER_TEXT_SIZE: usize = Self::PLAIN_TEXT_SIZE + size_of::<Tag>();
}

#[cfg(test)]
mod tests {
	use super::*;

	#[test]
	fn test_encrypted_block_plain_text_size() {
		assert_eq!(EncryptedBlock::PLAIN_TEXT_SIZE, 1_048_576);
	}

	#[test]
	fn test_one_shot_nonce_size() {
		assert_eq!(size_of::<OneShotNonce>(), 24);
	}

	#[test]
	fn test_stream_nonce_size() {
		assert_eq!(size_of::<StreamNonce>(), 20);
	}

	#[test]
	fn xchacha_tag_size() {
		assert_eq!(size_of::<Tag>(), 16);
	}

	#[test]
	fn test_encrypted_block_cipher_text_size() {
		assert_eq!(EncryptedBlock::CIPHER_TEXT_SIZE, 1_048_576 + 16);
	}
}
