use crate::marshal::resolver::handler::{self, Annotation, Key, Receiver as HandlerReceiver};
use commonware_actor::mailbox;
use commonware_cryptography::{Digest, PublicKey};
use commonware_p2p::{Blocker, Provider, Receiver as P2pReceiver, Sender};
use commonware_resolver::p2p;
use commonware_runtime::{BufferPooler, Clock, Metrics, Spawner};
use rand::Rng;
use std::{num::NonZeroUsize, time::Duration};
pub struct Config<P, C, B>
where
P: PublicKey,
C: Provider<PublicKey = P>,
B: Blocker<PublicKey = P>,
{
pub public_key: P,
pub peer_provider: C,
pub blocker: B,
pub mailbox_size: NonZeroUsize,
pub initial: Duration,
pub timeout: Duration,
pub fetch_retry_timeout: Duration,
pub priority_requests: bool,
pub priority_responses: bool,
}
pub type Mailbox<D, P> = p2p::Mailbox<Key<D>, P, Annotation>;
pub fn init<E, C, B, D, S, R, P>(
context: E,
config: Config<P, C, B>,
backfill: (S, R),
) -> (HandlerReceiver<D>, Mailbox<D, P>)
where
E: BufferPooler + Rng + Spawner + Clock + Metrics,
C: Provider<PublicKey = P>,
B: Blocker<PublicKey = P>,
D: Digest,
S: Sender<PublicKey = P>,
R: P2pReceiver<PublicKey = P>,
P: PublicKey,
{
let (sender, receiver) = mailbox::new(context.child("handler"), config.mailbox_size);
let handler = handler::Handler::new(sender);
let (resolver_engine, resolver) = p2p::Engine::new(
context.child("resolver"),
p2p::Config {
peer_provider: config.peer_provider,
blocker: config.blocker,
consumer: handler.clone(),
producer: handler,
mailbox_size: config.mailbox_size,
me: Some(config.public_key),
initial: config.initial,
timeout: config.timeout,
fetch_retry_timeout: config.fetch_retry_timeout,
priority_requests: config.priority_requests,
priority_responses: config.priority_responses,
},
);
resolver_engine.start(backfill);
(HandlerReceiver::new(receiver), resolver)
}