use super::{
approval_watch::{Answer, Expected},
permission::Decision,
};
use serde_json::Value;
pub(super) fn draft(
value: &Value,
id: &str,
expected: &Expected,
agent: &str,
store: &str,
) -> anyhow::Result<Option<Answer>> {
anyhow::ensure!(
value["id"] == id
&& value["holder"] == agent
&& value["request_digest"] == expected.digest
&& value["target"]["kind"] == "haematite.database"
&& value["target"]["id"] == store
&& value["target"]["action"] == "agent_permission",
"permission_draft_binding_differs"
);
let decision = match value["state"].as_str() {
Some("waiting") => return Ok(None),
Some("approved") => Decision::Approve,
Some("refused" | "refused_on_execution") => Decision::Refuse,
Some("executed") => Decision::Cancelled,
_ => anyhow::bail!("permission_draft_state_invalid"),
};
let person = value["decided_by"]
.as_str()
.filter(|person| !person.is_empty() && person.len() <= 128 && *person != agent)
.ok_or_else(|| anyhow::anyhow!("permission_draft_decider_invalid"))?;
anyhow::ensure!(
value["decided_at"].as_u64().is_some_and(|time| time > 0),
"permission_draft_decision_time_invalid"
);
Ok(Some(Answer {
draft: id.to_owned(),
decision,
person: person.to_owned(),
failure: None,
}))
}