use sp_std::vec::Vec;
use scale_info::TypeInfo;
use sp_runtime::RuntimeDebug;
use codec::{Encode, Decode};

use frame_support::BoundedVec;
use crate::ExodusError;

#[derive(Default, Encode, Decode, Clone, PartialEq, Eq, Ord, PartialOrd, RuntimeDebug, TypeInfo)]
#[scale_info(skip_type_params(T))]
pub struct EncryptionData<T: crate::pallet::Config> {
    pub ciphertext: BoundedVec<u8, crate::CiphertextMaxBytes<T>>,
    pub nonce: [u8; crate::ENCRYPTION_NONCE_MAX_BYTES as usize],
}

impl<T: crate::pallet::Config> EncryptionData<T> {
    pub fn try_new(
        ciphertext_vec: Vec<u8>,
        nonce_bytes: &[u8],
    ) -> Result<Self, ExodusError> {
        if nonce_bytes.len() != crate::ENCRYPTION_NONCE_MAX_BYTES as usize {
            return Err(ExodusError::EncryptionFailed);
        }

        let ciphertext =
            BoundedVec::<u8, crate::CiphertextMaxBytes<T>>::try_from(ciphertext_vec)
                .map_err(|_| ExodusError::EncryptionFailed)?;

        let mut nonce = [0u8; crate::ENCRYPTION_NONCE_MAX_BYTES as usize];
        nonce.copy_from_slice(nonce_bytes);

        Ok(Self { ciphertext, nonce })
    }
}
