use std::collections::{HashMap, HashSet};
use nostr::filter::Filter;
use nostr::types::RelayUrl;
use super::req_target::{InnerReqTarget, ReqTarget};
use crate::client::url::RelayUrlArg;
use crate::client::{Client, Error};
use crate::pool::RelayPool;
pub(super) async fn build_targets(
client: &Client,
target: ReqTarget<'_>,
) -> Result<HashMap<RelayUrl, Vec<Filter>>, Error> {
match client.gossip() {
Some(gossip) => match target.into_inner() {
InnerReqTarget::Auto(filters) => {
client.gossip_break_down_filters(gossip, filters).await
}
InnerReqTarget::Manual(target) => Ok(convert_filters_arg_vec_to_map(target)?),
},
None => Ok(convert_filters_arg_to_targets(client.pool(), target).await?),
}
}
async fn make_targets_from_filter_list(
pool: &RelayPool,
filters: Vec<Filter>,
) -> HashMap<RelayUrl, Vec<Filter>> {
let urls: HashSet<RelayUrl> = pool.read_relay_urls().await;
urls.into_iter().map(|u| (u, filters.clone())).collect()
}
async fn convert_filters_arg_to_targets(
pool: &RelayPool,
target: ReqTarget<'_>,
) -> Result<HashMap<RelayUrl, Vec<Filter>>, Error> {
match target.into_inner() {
InnerReqTarget::Auto(filters) => Ok(make_targets_from_filter_list(pool, filters).await),
InnerReqTarget::Manual(targets) => convert_filters_arg_vec_to_map(targets),
}
}
pub(super) fn convert_filters_arg_vec_to_map(
targeted: Vec<(RelayUrlArg<'_>, Vec<Filter>)>,
) -> Result<HashMap<RelayUrl, Vec<Filter>>, Error> {
let mut map: HashMap<RelayUrl, Vec<Filter>> = HashMap::with_capacity(targeted.len());
for (url_arg, filters) in targeted {
let url: RelayUrl = url_arg.try_into_relay_url()?.into_owned();
map.insert(url, filters);
}
Ok(map)
}