use std::convert::TryFrom;
use bamboo_rs_core::entry::MAX_ENTRY_SIZE;
use bamboo_rs_core::{Entry as BambooEntry, Signature as BambooSignature};
use crate::entry::{Entry, EntrySigned, EntrySignedError};
use crate::identity::KeyPair;
use crate::message::MessageEncoded;
pub fn sign_and_encode(entry: &Entry, key_pair: &KeyPair) -> Result<EntrySigned, EntrySignedError> {
let message_encoded = match entry.message() {
Some(message) => MessageEncoded::try_from(message)?,
None => return Err(EntrySignedError::MessageMissing),
};
let message_hash = message_encoded.hash();
let message_size = message_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_i64() as u64,
is_end_of_feed: false,
payload_hash: message_hash.into(),
payload_size: message_size as u64,
author: key_pair.public_key().to_owned(),
seq_num: entry.seq_num().as_i64() 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])
}