use std::convert::TryFrom;
use bamboo_rs_core_ed25519_yasmf::entry::MAX_ENTRY_SIZE;
use bamboo_rs_core_ed25519_yasmf::{Entry as BambooEntry, Signature as BambooSignature};
use crate::entry::{Entry, EntrySigned, EntrySignedError};
use crate::identity::KeyPair;
use crate::operation::OperationEncoded;
pub fn sign_and_encode(entry: &Entry, key_pair: &KeyPair) -> Result<EntrySigned, EntrySignedError> {
let operation_encoded = match entry.operation() {
Some(operation) => OperationEncoded::try_from(operation)?,
None => return Err(EntrySignedError::OperationMissing),
};
let operation_hash = operation_encoded.hash();
let operation_size = operation_encoded.size();
let backlink = entry.backlink_hash().map(|link| link.to_owned().into());
let lipmaa_link = if entry.is_skiplink_required() {
if entry.skiplink_hash().is_none() {
return Err(EntrySignedError::SkiplinkMissing);
}
entry.skiplink_hash().map(|link| link.to_owned().into())
} else {
None
};
let mut entry: BambooEntry<_, &[u8]> = BambooEntry {
log_id: entry.log_id().as_u64(),
is_end_of_feed: false,
payload_hash: operation_hash.into(),
payload_size: operation_size,
author: key_pair.public_key().to_owned(),
seq_num: entry.seq_num().as_u64(),
backlink,
lipmaa_link,
sig: None,
};
let mut entry_bytes = [0u8; MAX_ENTRY_SIZE];
let entry_size = entry.encode(&mut entry_bytes)?;
let signature = key_pair.sign(&entry_bytes[..entry_size]);
let signature_bytes = signature.to_bytes();
entry.sig = Some(BambooSignature(&signature_bytes[..]));
let signed_entry_size = entry.encode(&mut entry_bytes)?;
EntrySigned::try_from(&entry_bytes[..signed_entry_size])
}