use std::convert::TryInto;
use bamboo_rs_core_ed25519_yasmf::entry::MAX_ENTRY_SIZE;
use bamboo_rs_core_ed25519_yasmf::{Signature as BambooSignature, YasmfHash};
use lipmaa_link::is_skip_link;
use rstest::fixture;
use varu64::encode as varu64_encode;
use crate::entry::encode::{encode_entry, sign_entry};
use crate::entry::{EncodedEntry, Entry};
use crate::hash::{Blake3ArrayVec, Hash};
use crate::identity::KeyPair;
use crate::operation::EncodedOperation;
use crate::test_utils::fixtures::{encoded_operation, key_pair, random_hash};
#[fixture]
pub fn entry(
#[default(1)] seq_num: u64,
#[default(0)] log_id: u64,
#[default(None)] backlink: Option<Hash>,
#[default(None)] skiplink: Option<Hash>,
#[from(encoded_operation)] encoded_operation: EncodedOperation,
#[from(key_pair)] key_pair: KeyPair,
) -> Entry {
sign_entry(
&log_id.into(),
&seq_num.try_into().unwrap(),
skiplink.as_ref(),
backlink.as_ref(),
&encoded_operation,
&key_pair,
)
.unwrap()
}
#[fixture]
pub fn entry_auto_gen_links(
#[default(1)] seq_num: u64,
#[default(0)] log_id: u64,
#[from(encoded_operation)] encoded_operation: EncodedOperation,
#[from(key_pair)] key_pair: KeyPair,
) -> Entry {
let backlink = match seq_num {
1 => None,
_ => Some(random_hash()),
};
let skiplink = match is_skip_link(seq_num) {
false => None,
true => Some(random_hash()),
};
entry(
seq_num,
log_id,
backlink,
skiplink,
encoded_operation,
key_pair,
)
}
#[fixture]
pub fn encoded_entry(
#[default(1)] seq_num: u64,
#[default(0)] log_id: u64,
#[default(None)] backlink: Option<Hash>,
#[default(None)] skiplink: Option<Hash>,
#[from(encoded_operation)] encoded_operation: EncodedOperation,
#[from(key_pair)] key_pair: KeyPair,
) -> EncodedEntry {
let entry = sign_entry(
&log_id.into(),
&seq_num.try_into().unwrap(),
skiplink.as_ref(),
backlink.as_ref(),
&encoded_operation,
&key_pair,
)
.unwrap();
encode_entry(&entry).unwrap()
}
#[fixture]
pub fn entry_signed_encoded_unvalidated(
#[default(1)] seq_num: u64,
#[default(0)] log_id: u64,
#[default(None)] backlink: Option<Hash>,
#[default(None)] skiplink: Option<Hash>,
#[default(None)] operation: Option<EncodedOperation>,
#[from(key_pair)] key_pair: KeyPair,
) -> EncodedEntry {
let mut entry_bytes = [0u8; MAX_ENTRY_SIZE];
let mut next_byte_num = 0;
entry_bytes[0] = 0;
next_byte_num += 1;
let author_bytes = key_pair.public_key().to_bytes();
entry_bytes[next_byte_num..author_bytes.len() + next_byte_num]
.copy_from_slice(&author_bytes[..]);
next_byte_num += author_bytes.len();
next_byte_num += varu64_encode(log_id, &mut entry_bytes[next_byte_num..]);
next_byte_num += varu64_encode(seq_num, &mut entry_bytes[next_byte_num..]);
next_byte_num = match skiplink {
Some(lipmaa_link) => {
next_byte_num += Into::<YasmfHash<Blake3ArrayVec>>::into(&lipmaa_link)
.encode(&mut entry_bytes[next_byte_num..])
.unwrap();
next_byte_num
}
_ => next_byte_num,
};
next_byte_num = match backlink {
Some(backlink) => {
next_byte_num += Into::<YasmfHash<Blake3ArrayVec>>::into(&backlink)
.encode(&mut entry_bytes[next_byte_num..])
.unwrap();
next_byte_num
}
_ => next_byte_num,
};
match operation {
Some(operation) => {
let operation_size = operation.size();
next_byte_num += varu64_encode(operation_size, &mut entry_bytes[next_byte_num..]);
let operation_hash = operation.hash();
next_byte_num += Into::<YasmfHash<Blake3ArrayVec>>::into(&operation_hash)
.encode(&mut entry_bytes[next_byte_num..])
.unwrap();
}
None => (),
};
let signature = key_pair.sign(&entry_bytes[..next_byte_num]);
let signature_bytes = signature.to_bytes();
let sig = Some(BambooSignature(&signature_bytes[..])).unwrap();
next_byte_num += sig.encode(&mut entry_bytes[next_byte_num..]).unwrap();
EncodedEntry::from_bytes(&entry_bytes[..next_byte_num])
}