use std::sync::Arc;
use tokio::sync::RwLock;
use serde_json::Value as JsonValue;
use crate::config::AppConfig;
use crate::error::AppError;
use crate::store::KeyspaceHandle;
use crate::webvh_store;
use vta_sdk::webvh::WebvhDidRecord;
use super::document::{CurrentDocumentError, current_document_from_log};
#[derive(Debug, Clone)]
pub struct VtaDocState {
pub vta_did: String,
pub scid: String,
pub did_log: String,
pub current_doc: JsonValue,
pub record: WebvhDidRecord,
}
#[derive(Debug, thiserror::Error)]
pub enum ProtocolPreconditionError {
#[error("VTA DID is not configured — run `vta setup` first")]
VtaDidNotConfigured,
#[error("VTA DID `{0}` has no webvh record — re-run `vta setup`")]
VtaDidRecordMissing(String),
#[error("VTA DID `{0}` has no published log on disk")]
VtaDidLogMissing(String),
#[error("the on-disk did.jsonl is empty — cannot read current document")]
EmptyLog,
#[error("storage error while loading VTA document state: {0}")]
Storage(String),
#[error("could not parse the VTA's current DID document from the log: {0}")]
DocumentParse(String),
}
impl From<AppError> for ProtocolPreconditionError {
fn from(value: AppError) -> Self {
Self::Storage(value.to_string())
}
}
impl From<CurrentDocumentError> for ProtocolPreconditionError {
fn from(value: CurrentDocumentError) -> Self {
match value {
CurrentDocumentError::EmptyLog => Self::EmptyLog,
CurrentDocumentError::Parse(s) => Self::DocumentParse(s),
}
}
}
pub async fn load_vta_doc_state(
config: &Arc<RwLock<AppConfig>>,
webvh_ks: &KeyspaceHandle,
) -> Result<VtaDocState, ProtocolPreconditionError> {
let vta_did = {
let cfg = config.read().await;
cfg.vta_did
.clone()
.ok_or(ProtocolPreconditionError::VtaDidNotConfigured)?
};
let record = webvh_store::get_did(webvh_ks, &vta_did)
.await?
.ok_or_else(|| ProtocolPreconditionError::VtaDidRecordMissing(vta_did.clone()))?;
let scid = record.scid.clone();
let did_log = webvh_store::get_did_log(webvh_ks, &vta_did)
.await?
.ok_or_else(|| ProtocolPreconditionError::VtaDidLogMissing(vta_did.clone()))?;
let current_doc = current_document_from_log(&did_log)?;
Ok(VtaDocState {
vta_did,
scid,
did_log,
current_doc,
record,
})
}