use std::convert::TryFrom;
use serde::{Deserialize, Serialize};
use wasm_bindgen::prelude::wasm_bindgen;
use wasm_bindgen::JsValue;
use crate::entry::{decode_entry as decode, sign_and_encode, Entry, EntrySigned, LogId, SeqNum};
use crate::hash::Hash;
use crate::operation::{Operation, OperationEncoded};
use crate::wasm::error::jserr;
use crate::wasm::serde::serialize_to_js;
use crate::wasm::KeyPair;
#[derive(Serialize, Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
pub struct SignEncodeEntryResult {
pub entry_encoded: String,
pub entry_hash: String,
pub operation_hash: String,
}
#[wasm_bindgen(js_name = signEncodeEntry)]
pub fn sign_encode_entry(
key_pair: &KeyPair,
encoded_operation: String,
entry_skiplink_hash: Option<String>,
entry_backlink_hash: Option<String>,
seq_num: u64,
log_id: u64,
) -> Result<JsValue, JsValue> {
let skiplink_hash = match entry_skiplink_hash {
Some(hash) => Some(jserr!(Hash::new(&hash))),
None => None,
};
let backlink_hash = match entry_backlink_hash {
Some(hash) => Some(jserr!(Hash::new(&hash))),
None => None,
};
let seq_num = jserr!(SeqNum::new(seq_num));
let operation_encoded = jserr!(OperationEncoded::new(&encoded_operation));
let operation = jserr!(Operation::try_from(&operation_encoded));
let entry = jserr!(Entry::new(
&LogId::new(log_id),
Some(&operation),
skiplink_hash.as_ref(),
backlink_hash.as_ref(),
&seq_num,
));
let entry_signed = jserr!(sign_and_encode(&entry, key_pair.as_inner()));
let entry_operation_bundle = SignEncodeEntryResult {
entry_encoded: entry_signed.as_str().into(),
entry_hash: entry_signed.hash().as_str().into(),
operation_hash: operation_encoded.hash().as_str().into(),
};
let result = jserr!(serialize_to_js(&entry_operation_bundle));
Ok(result)
}
#[wasm_bindgen(js_name = decodeEntry)]
pub fn decode_entry(
entry_encoded: String,
operation_encoded: Option<String>,
) -> Result<JsValue, JsValue> {
let operation_encoded = match operation_encoded {
Some(msg) => {
let inner = jserr!(OperationEncoded::new(&msg));
Some(inner)
}
None => None,
};
let entry_signed = jserr!(EntrySigned::new(&entry_encoded));
let entry: Entry = jserr!(decode(&entry_signed, operation_encoded.as_ref()));
let result = jserr!(serialize_to_js(&entry));
Ok(result)
}