use std::path::PathBuf;
use clap::Args;
use onomancy_core::anchor::doc::DocAnchor;
use onomancy_dnssec::{dns_name::DnsName, txt::generation_key::GenerationKey};
use onomancy_keyhive::{authority::KeyhiveAuthority, mint};
use onomancy_publish::{ceremony::bind::Bind as BindCeremony, signer::Signer};
use crate::{
now_ms, plan_io,
seed::{self, SeedError},
};
#[derive(Debug, Args)]
pub(crate) struct Bind {
#[arg(long)]
hostname: String,
#[arg(long)]
doc_key: Option<PathBuf>,
#[arg(long, conflicts_with = "doc_key")]
doc_seed: Option<String>,
#[arg(long)]
generation_key: Option<PathBuf>,
#[arg(long, conflicts_with = "generation_key")]
generation_seed: Option<String>,
#[arg(long, default_value = ".")]
out_dir: PathBuf,
}
impl Bind {
pub(crate) fn run(&self) -> Result<(), BindError> {
let hostname = DnsName::parse_display(&self.hostname)?;
let doc_key = seed::load(self.doc_seed.as_deref(), self.doc_key.as_deref())?;
let generation_key = seed::load(
self.generation_seed.as_deref(),
self.generation_key.as_deref(),
)?;
let carriage = mint::generation_carriage(&doc_key, &generation_key)?;
let plan = BindCeremony {
hostname,
document: DocAnchor::from(doc_key.verifying_key()),
generation: GenerationKey::from(generation_key.verifying_key()),
heads: vec![],
lineage: vec![],
carriage,
}
.plan(now_ms(), &Signer::new(doc_key), &KeyhiveAuthority)?;
crate::block_on(plan_io::execute(&plan, &self.out_dir))??;
Ok(())
}
}
#[derive(Debug, thiserror::Error)]
pub(crate) enum BindError {
#[error(transparent)]
Ceremony(#[from] onomancy_publish::ceremony::CeremonyError),
#[error(transparent)]
Mint(#[from] onomancy_keyhive::mint::MintError),
#[error("hostname: {0}")]
Hostname(#[from] onomancy_dnssec::dns_name::ParseDnsNameError),
#[error(transparent)]
Io(#[from] std::io::Error),
#[error(transparent)]
Seed(#[from] SeedError),
}