// Copyright 2021 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

use {
    crate::target::Target,
    crate::target::TargetAddrType,
    crate::MDNS_MAX_AGE,
    addr::TargetAddr,
    anyhow::Result,
    async_trait::async_trait,
    chrono::Utc,
    ffx::DaemonError,
    ffx_daemon_core::events::{self, EventSynthesizer},
    ffx_daemon_events::{DaemonEvent, TargetEvent, TargetInfo},
    fidl_fuchsia_developer_ffx as ffx,
    std::cell::RefCell,
    std::collections::HashMap,
    std::fmt::Debug,
    std::net::IpAddr,
    std::rc::Rc,
};

#[derive(Default)]
pub struct TargetCollection {
    targets: RefCell<HashMap<u64, Rc<Target>>>,
    events: RefCell<Option<events::Queue<DaemonEvent>>>,
}

#[async_trait(?Send)]
impl EventSynthesizer<DaemonEvent> for TargetCollection {
    async fn synthesize_events(&self) -> Vec<DaemonEvent> {
        // TODO(awdavies): This won't be accurate once a target is able to create
        // more than one event at a time.
        let mut res = Vec::with_capacity(self.targets.borrow().len());
        let targets = self.targets.borrow().values().cloned().collect::<Vec<_>>();
        for target in targets.into_iter() {
            if target.is_connected() {
                res.push(DaemonEvent::NewTarget(target.target_info()));
            }
        }
        res
    }
}

impl TargetCollection {
    pub fn new() -> Self {
        Self { targets: RefCell::new(HashMap::new()), events: RefCell::new(None) }
    }

    #[cfg(test)]
    fn new_with_queue() -> Rc<Self> {
        let target_collection = Rc::new(Self::new());
        let queue = events::Queue::new(&target_collection);
        target_collection.set_event_queue(queue);
        target_collection
    }

    pub fn set_event_queue(&self, q: events::Queue<DaemonEvent>) {
        self.events.replace(Some(q));
    }

    pub fn targets(&self) -> Vec<Rc<Target>> {
        self.targets.borrow().values().cloned().collect()
    }

    pub fn is_empty(&self) -> bool {
        self.targets.borrow().len() == 0
    }

    pub fn remove_target(&self, target_id: String) -> bool {
        if let Some(t) = self.get(target_id) {
            let target = self.targets.borrow_mut().remove(&t.id());
            if let Some(target) = target {
                target.disconnect()
            }
            true
        } else {
            false
        }
    }

    pub fn remove_ephemeral_target(&self, target: Rc<Target>) -> bool {
        self.targets.borrow_mut().remove(&target.id()).is_some()
    }

    fn find_matching_target(&self, new_target: &Target) -> Option<Rc<Target>> {
        // Look for a target by primary ID first
        let new_ids = new_target.ids();
        let mut to_update =
            new_ids.iter().find_map(|id| self.targets.borrow().get(id).map(|t| t.clone()));

        // If we haven't yet found a target, try to find one by all IDs, nodename, serial, or address.
        if to_update.is_none() {
            let new_nodename = new_target.nodename();
            let new_ips =
                new_target.addrs().iter().map(|addr| addr.ip().clone()).collect::<Vec<IpAddr>>();
            let new_port = new_target.ssh_port();
            let new_serial = new_target.serial();

            for target in self.targets.borrow().values() {
                let serials_match = || match (target.serial().as_ref(), new_serial.as_ref()) {
                    (Some(s), Some(other_s)) => s == other_s,
                    _ => false,
                };

                // Only match the new nodename if it is Some and the same.
                let nodenames_match = || match (&new_nodename, target.nodename()) {
                    (Some(ref left), Some(ref right)) => left == right,
                    _ => false,
                };

                if target.has_id(new_ids.iter())
                    || serials_match()
                    || nodenames_match()
                    // Only match against addresses if the ports are the same
                    || (target.ssh_port() == new_port
                        && target.addrs().iter().any(|addr| new_ips.contains(&addr.ip())))
                {
                    to_update.replace(target.clone());
                    break;
                }
            }
        }

        to_update
    }

    #[tracing::instrument(level = "info", skip(self))]
    pub fn merge_insert(&self, new_target: Rc<Target>) -> Rc<Target> {
        // Drop non-manual loopback address entries, as matching against
        // them could otherwise match every target in the collection.
        new_target.drop_loopback_addrs();

        let to_update = self.find_matching_target(&new_target);

        log::trace!("Merging target {:?} into {:?}", new_target, to_update);

        // Do not merge unscoped link-local addresses into the target
        // collection, as they are not routable and therefore not safe
        // for connecting to the remote, and may collide with other
        // scopes.
        new_target.drop_unscoped_link_local_addrs();

        if let Some(to_update) = to_update {
            if let Some(config) = new_target.build_config() {
                to_update.build_config.borrow_mut().replace(config);
            }
            if let Some(serial) = new_target.serial() {
                to_update.serial.borrow_mut().replace(serial);
            }
            if let Some(new_name) = new_target.nodename() {
                to_update.set_nodename(new_name);
            }

            to_update.update_last_response(new_target.last_response());
            let mut addrs = new_target.addrs.borrow().iter().cloned().collect::<Vec<_>>();
            addrs.sort_by(|a, b| b.timestamp.cmp(&a.timestamp));
            to_update.addrs_extend(addrs.into_iter());
            to_update.addrs.borrow_mut().retain(|t| {
                let is_too_old = Utc::now().signed_duration_since(t.timestamp).num_milliseconds()
                    as i128
                    > MDNS_MAX_AGE.as_millis() as i128;
                !is_too_old || matches!(t.addr_type, TargetAddrType::Manual(_))
            });
            to_update.update_boot_timestamp(new_target.boot_timestamp_nanos());

            to_update.update_connection_state(|_| new_target.get_connection_state());

            to_update.events.push(TargetEvent::Rediscovered).unwrap_or_else(|err| {
                log::warn!("unable to enqueue rediscovered event: {:#}", err)
            });
            if let Some(event_queue) = self.events.borrow().as_ref() {
                event_queue
                    .push(DaemonEvent::UpdatedTarget(new_target.target_info()))
                    .unwrap_or_else(|e| log::warn!("unalbe to push target update event: {}", e));
            }
            to_update
        } else {
            self.targets.borrow_mut().insert(new_target.id(), new_target.clone());

            if let Some(event_queue) = self.events.borrow().as_ref() {
                event_queue
                    .push(DaemonEvent::NewTarget(new_target.target_info()))
                    .unwrap_or_else(|e| log::warn!("unable to push new target event: {}", e));
            }

            new_target
        }
    }

    /// wait_for_match attempts to find a target matching "matcher". If no
    /// matcher is provided, either the default target is matched, or, if there
    /// is no default a single target is returned iff it is the only target in
    /// the collection. If there is neither a matcher or a defualt, and there are
    /// several targets in the collection when the query starts, a
    /// DaemonError::TargetAmbiguous error is returned. The matcher is converted to a
    /// TargetQuery for matching, and follows the TargetQuery semantics.
    pub async fn wait_for_match(&self, matcher: Option<String>) -> Result<Rc<Target>, DaemonError> {
        // If there's nothing to match against, unblock on the first target.
        let target_query = TargetQuery::from(matcher.clone());

        // If there is no matcher, and there are already multiple targets in the
        // target collection, we know that the target is ambiguous and thus
        // produce an actionable error to the user.
        if let TargetQuery::First = target_query {
            // PERFORMANCE: it's possible to avoid the discarded clones here, with more work.

            // This is a stop-gap UX check. The other option is to
            // just display disconnected targets in `ffx target list` to make it
            // clear that an ambiguous target error is about having more than
            // one target in the cache rather than giving an ambiguous target
            // error around targets that cannot be displayed in the frontend.
            if self.targets.borrow().values().filter(|t| t.is_connected()).count() > 1 {
                return Err(DaemonError::TargetAmbiguous);
            }
        }

        // Infinite timeout here is fine, as the client dropping connection
        // will lead to this being cleaned up eventually. It is the client's
        // responsibility to determine their respective timeout(s).
        self.events
            .borrow()
            .as_ref()
            .expect("target event queue must be initialized by now")
            .wait_for(None, move |e| match e {
                DaemonEvent::NewTarget(ref target_info)
                | DaemonEvent::UpdatedTarget(ref target_info) => {
                    target_query.match_info(target_info)
                }
                _ => false,
            })
            .await
            .map_err(|e| {
                log::warn!("{}", e);
                DaemonError::TargetCacheError
            })?;

        // TODO(awdavies): It's possible something might happen between the new
        // target event and now, so it would make sense to give the
        // user some information on what happened: likely something
        // to do with the target suddenly being forced out of the cache
        // (this isn't a problem yet, but will be once more advanced
        // lifetime tracking is implemented). If a name isn't specified it's
        // possible a secondary/tertiary target showed up, and those cases are
        // handled here.
        self.get_connected(matcher).ok_or(DaemonError::TargetNotFound)
    }

    pub fn get_connected<TQ>(&self, tq: TQ) -> Option<Rc<Target>>
    where
        TQ: Into<TargetQuery>,
    {
        let target_query: TargetQuery = tq.into();

        self.targets
            .borrow()
            .values()
            .filter(|t| t.is_connected())
            .filter(|target| target_query.matches(target))
            .cloned()
            .next()
    }

    pub fn get<TQ>(&self, t: TQ) -> Option<Rc<Target>>
    where
        TQ: Into<TargetQuery>,
    {
        let query: TargetQuery = t.into();
        self.targets
            .borrow()
            .values()
            // TODO(raggi): cleanup query matching so that targets can match themselves against a query
            .find(|target| query.match_info(&target.target_info()))
            .map(Clone::clone)
    }
}

pub trait MatchTarget {
    fn match_target<TQ>(self, t: TQ) -> Option<Target>
    where
        TQ: Into<TargetQuery>;
}

#[derive(Debug)]
pub enum TargetQuery {
    /// Attempts to match the nodename, falling back to serial (in that order).
    NodenameOrSerial(String),
    AddrPort((TargetAddr, u16)),
    Addr(TargetAddr),
    First,
}

impl TargetQuery {
    pub fn match_info(&self, t: &TargetInfo) -> bool {
        match self {
            Self::NodenameOrSerial(arg) => {
                if let Some(ref nodename) = t.nodename {
                    if nodename.contains(arg) {
                        return true;
                    }
                }
                if let Some(ref serial) = t.serial {
                    if serial.contains(arg) {
                        return true;
                    }
                }
                false
            }
            Self::AddrPort((addr, port)) => {
                let no_port_and_zero = *port == 0 && t.ssh_port.is_none();
                let ports_equal = t.ssh_port.unwrap_or(22) == *port;
                (no_port_and_zero || ports_equal) && Self::Addr(*addr).match_info(t)
            }
            Self::Addr(addr) => t.addresses.iter().any(|a| {
                // If the query does not contain a scope, allow a match against
                // only the IP.
                a == addr || addr.scope_id() == 0 && a.ip() == addr.ip()
            }),
            Self::First => true,
        }
    }

    pub fn matches(&self, t: &Target) -> bool {
        self.match_info(&t.target_info())
    }
}

impl<T> From<Option<T>> for TargetQuery
where
    T: Into<TargetQuery>,
{
    fn from(o: Option<T>) -> Self {
        o.map(Into::into).unwrap_or(Self::First)
    }
}

impl From<&str> for TargetQuery {
    fn from(s: &str) -> Self {
        String::from(s).into()
    }
}

impl From<String> for TargetQuery {
    /// If the string can be parsed as some kind of IP address, will attempt to
    /// match based on that, else fall back to the nodename or serial matches.
    fn from(s: String) -> Self {
        if s == "" {
            return Self::First;
        }
        let (addr, scope, port) = match netext::parse_address_parts(s.as_str()) {
            Ok(r) => r,
            Err(e) => {
                log::trace!("Failed to parse address. Interpreting as nodename: {:?}", e);
                return Self::NodenameOrSerial(s);
            }
        };
        let scope = scope
            .map(|s| {
                // If this ends up being a number and is a valid scope ID, then this will return
                // the name. If not it will return the index number as a string (so something like
                // "3"). When running name_to_scope_id, using the index as a string will fail,
                // causing that function to return zero, which is the desired effect.
                //
                // Returning 0 from this closure will set the TargetAddr scope_id to 0 as well,
                // which is the same as not including a scope_id in the query. This will still
                // match a target later if the scope has gone down (manually or otherwise), which
                // is why it is not included as an error for searching. This does mean it might
                // be possible to include arbitrary inaccurate scope names for looking up a target,
                // however, like `fe80::1%nonsense`.
                let s =
                    s.parse::<u32>().map(|i| netext::scope_id_to_name(i)).unwrap_or(s.to_owned());
                netext::name_to_scope_id(s.as_str())
            })
            .unwrap_or(0);
        match port {
            Some(p) => Self::AddrPort((TargetAddr::from((addr, scope)), p)),
            None => Self::Addr(TargetAddr::from((addr, scope))),
        }
    }
}

impl From<TargetAddr> for TargetQuery {
    fn from(t: TargetAddr) -> Self {
        Self::Addr(t)
    }
}

#[cfg(test)]
mod tests {
    use {
        super::*,
        crate::target::clone_target,
        crate::target::{TargetAddrEntry, TargetAddrType},
        chrono::{TimeZone, Utc},
        ffx_daemon_events::TargetConnectionState,
        fuchsia_async::Task,
        futures::prelude::*,
        std::collections::BTreeSet,
        std::net::{Ipv4Addr, Ipv6Addr},
        std::pin::Pin,
        std::task::{Context, Poll},
        std::time::Instant,
    };

    #[fuchsia_async::run_singlethreaded(test)]
    async fn test_target_collection_insert_new_not_connected() {
        let tc = TargetCollection::new_with_queue();
        let nodename = String::from("what");
        let t = Target::new_with_time(&nodename, Utc.ymd(2014, 10, 31).and_hms(9, 10, 12));
        tc.merge_insert(clone_target(&t));
        let other_target = tc.get(nodename.clone()).unwrap();
        assert_eq!(other_target, t);
        match tc.get_connected(nodename.clone()) {
            Some(_) => panic!("string lookup should return None"),
            _ => (),
        }
        let now = Instant::now();
        other_target.update_connection_state(|s| {
            assert_eq!(s, TargetConnectionState::Disconnected);
            TargetConnectionState::Mdns(now)
        });
        t.update_connection_state(|s| {
            assert_eq!(s, TargetConnectionState::Disconnected);
            TargetConnectionState::Mdns(now)
        });
        assert_eq!(&tc.get_connected(nodename.clone()).unwrap(), &t);
    }

    #[fuchsia_async::run_singlethreaded(test)]
    async fn test_target_collection_insert_new() {
        let tc = TargetCollection::new_with_queue();
        let nodename = String::from("what");
        let t = Target::new_with_time(&nodename, Utc.ymd(2014, 10, 31).and_hms(9, 10, 12));
        tc.merge_insert(t.clone());
        assert_eq!(tc.get(nodename.clone()).unwrap(), t);
        match tc.get("oihaoih") {
            Some(_) => panic!("string lookup should return None"),
            _ => (),
        }
    }

    #[fuchsia_async::run_singlethreaded(test)]
    async fn test_target_merge_evict_old_addresses() {
        let tc = TargetCollection::new_with_queue();
        let nodename = String::from("schplew");
        let t = Target::new_with_time(&nodename, Utc.ymd(2014, 10, 31).and_hms(9, 10, 12));
        let a1 = IpAddr::V4(Ipv4Addr::new(192, 168, 1, 1));
        let a2 = IpAddr::V6(Ipv6Addr::new(
            0xfe80, 0xcafe, 0xf00d, 0xf000, 0xb412, 0xb455, 0x1337, 0xfeed,
        ));
        let a3 = IpAddr::V6(Ipv6Addr::new(0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1));
        let tae1 = TargetAddrEntry {
            addr: (a1, 1).into(),
            timestamp: Utc.ymd(2014, 10, 31).and_hms(9, 10, 12),
            addr_type: TargetAddrType::Ssh,
        };
        let tae2 = TargetAddrEntry {
            addr: (a2, 1).into(),
            timestamp: Utc.ymd(2014, 10, 31).and_hms(9, 10, 12),
            addr_type: TargetAddrType::Ssh,
        };
        let tae3 = TargetAddrEntry {
            addr: (a3, 1).into(),
            timestamp: Utc.ymd(2014, 10, 31).and_hms(9, 10, 12),
            addr_type: TargetAddrType::Manual(None),
        };
        t.addrs.borrow_mut().insert(tae1);
        t.addrs.borrow_mut().insert(tae2);
        t.addrs.borrow_mut().insert(tae3);
        tc.merge_insert(clone_target(&t));
        let t2 = Target::new_with_time(&nodename, Utc.ymd(2014, 11, 2).and_hms(13, 2, 1));
        let a1 = IpAddr::V4(Ipv4Addr::new(192, 168, 1, 10));
        t2.addrs_insert((a1.clone(), 1).into());
        let merged_target = tc.merge_insert(t2);
        assert_eq!(merged_target.nodename(), Some(nodename));
        assert_eq!(merged_target.addrs().len(), 2);
        assert!(merged_target.addrs().contains(&(a1, 1).into()));
        assert!(merged_target.addrs().contains(&(a3, 1).into()));
    }

    #[fuchsia_async::run_singlethreaded(test)]
    async fn test_target_collection_merge() {
        let tc = TargetCollection::new_with_queue();
        let nodename = String::from("bananas");
        let t1 = Target::new_with_time(&nodename, Utc.ymd(2014, 10, 31).and_hms(9, 10, 12));
        let t2 = Target::new_with_time(&nodename, Utc.ymd(2014, 11, 2).and_hms(13, 2, 1));
        let a1 = IpAddr::V4(Ipv4Addr::new(192, 168, 1, 1));
        let a2 = IpAddr::V6(Ipv6Addr::new(
            0xfe80, 0xcafe, 0xf00d, 0xf000, 0xb412, 0xb455, 0x1337, 0xfeed,
        ));
        t1.addrs_insert((a1.clone(), 1).into());
        t2.addrs_insert((a2.clone(), 1).into());
        tc.merge_insert(clone_target(&t2));
        tc.merge_insert(clone_target(&t1));
        let merged_target = tc.get(nodename.clone()).unwrap();
        assert_ne!(merged_target, t1);
        assert_ne!(merged_target, t2);
        assert_eq!(merged_target.addrs().len(), 2);
        assert_eq!(*merged_target.last_response.borrow(), Utc.ymd(2014, 11, 2).and_hms(13, 2, 1));
        assert!(merged_target.addrs().contains(&(a1, 1).into()));
        assert!(merged_target.addrs().contains(&(a2, 1).into()));

        // Insert another instance of the a2 address, but with a missing
        // scope_id, and ensure that the new address does not affect the address
        // collection.
        let t3 = Target::new_with_time(&nodename, Utc.ymd(2014, 10, 31).and_hms(9, 10, 12));
        t3.addrs_insert((a2.clone(), 0).into());
        tc.merge_insert(clone_target(&t3));
        let merged_target = tc.get(nodename.clone()).unwrap();
        assert_eq!(merged_target.addrs().len(), 2);

        // Insert another instance of the a2 address, but with a new scope_id, and ensure that the new scope is used.
        let t3 = Target::new_with_time(&nodename, Utc.ymd(2014, 10, 31).and_hms(9, 10, 12));
        t3.addrs_insert((a2.clone(), 3).into());
        tc.merge_insert(clone_target(&t3));
        let merged_target = tc.get(nodename.clone()).unwrap();
        assert_eq!(merged_target.addrs().iter().filter(|addr| addr.scope_id() == 3).count(), 1);
    }

    #[fuchsia_async::run_singlethreaded(test)]
    async fn test_target_collection_no_scopeless_ipv6() {
        let tc = TargetCollection::new_with_queue();
        let nodename = String::from("bananas");
        let t1 = Target::new_with_time(&nodename, Utc.ymd(2014, 10, 31).and_hms(9, 10, 12));
        let t2 = Target::new_with_time(&nodename, Utc.ymd(2014, 11, 2).and_hms(13, 2, 1));
        let a1 = IpAddr::V4(Ipv4Addr::new(192, 168, 1, 1));
        let a2 = IpAddr::V6(Ipv6Addr::new(
            0xfe80, 0x0000, 0x0000, 0x0000, 0xb412, 0xb455, 0x1337, 0xfeed,
        ));
        t1.addrs_insert((a1.clone(), 0).into());
        t2.addrs_insert((a2.clone(), 0).into());
        tc.merge_insert(clone_target(&t2));
        tc.merge_insert(clone_target(&t1));
        let merged_target = tc.get(nodename.clone()).unwrap();
        assert_ne!(&merged_target, &t1);
        assert_ne!(&merged_target, &t2);
        assert_eq!(merged_target.addrs().len(), 1);
        assert_eq!(*merged_target.last_response.borrow(), Utc.ymd(2014, 11, 2).and_hms(13, 2, 1));
        assert!(merged_target.addrs().contains(&(a1, 0).into()));
        assert!(!merged_target.addrs().contains(&(a2, 0).into()));
    }

    #[fuchsia_async::run_singlethreaded(test)]
    async fn test_target_by_addr() {
        let addr: TargetAddr = (IpAddr::from([192, 168, 0, 1]), 0).into();
        let t = Target::new_named("foo");
        t.addrs_insert(addr.clone());
        let tc = TargetCollection::new_with_queue();
        tc.merge_insert(clone_target(&t));
        assert_eq!(tc.get(addr).unwrap(), t);
        assert_eq!(tc.get("192.168.0.1").unwrap(), t);
        assert!(tc.get("fe80::dead:beef:beef:beef").is_none());

        let addr: TargetAddr =
            (IpAddr::from([0xfe80, 0x0, 0x0, 0x0, 0xdead, 0xbeef, 0xbeef, 0xbeef]), 3).into();
        let t = Target::new_named("fooberdoober");
        t.addrs_insert(addr.clone());
        tc.merge_insert(clone_target(&t));
        assert_eq!(tc.get("fe80::dead:beef:beef:beef").unwrap(), t);
        assert_eq!(tc.get(addr.clone()).unwrap(), t);
        assert_eq!(tc.get("fooberdoober").unwrap(), t);
    }

    #[fuchsia_async::run_singlethreaded(test)]
    async fn test_new_target_event_synthesis() {
        let t = Target::new_named("clopperdoop");
        let tc = TargetCollection::new_with_queue();
        tc.merge_insert(t.clone());
        let vec = tc.synthesize_events().await;
        assert_eq!(vec.len(), 0);
        t.update_connection_state(|s| {
            assert_eq!(s, TargetConnectionState::Disconnected);
            TargetConnectionState::Mdns(Instant::now())
        });
        let vec = tc.synthesize_events().await;
        assert_eq!(vec.len(), 1);
        assert_eq!(
            vec.iter().next().expect("events empty"),
            &DaemonEvent::NewTarget(TargetInfo {
                nodename: Some("clopperdoop".to_string()),
                ..Default::default()
            })
        );
    }

    #[fuchsia_async::run_singlethreaded(test)]
    async fn test_target_collection_event_synthesis_all_connected() {
        let t = Target::new_autoconnected("clam-chowder-is-tasty");
        let t2 = Target::new_autoconnected("this-is-a-crunchy-falafel");
        let t3 = Target::new_autoconnected("i-should-probably-eat-lunch");
        let t4 = Target::new_autoconnected("i-should-probably-eat-lunch");
        let tc = TargetCollection::new_with_queue();
        tc.merge_insert(t);
        tc.merge_insert(t2);
        tc.merge_insert(t3);
        tc.merge_insert(t4);

        let events = tc.synthesize_events().await;
        assert_eq!(events.len(), 3);
        assert!(events.iter().any(|e| e
            == &DaemonEvent::NewTarget(TargetInfo {
                nodename: Some("clam-chowder-is-tasty".to_string()),
                ..Default::default()
            })));
        assert!(events.iter().any(|e| e
            == &DaemonEvent::NewTarget(TargetInfo {
                nodename: Some("this-is-a-crunchy-falafel".to_string()),
                ..Default::default()
            })));
        assert!(events.iter().any(|e| e
            == &DaemonEvent::NewTarget(TargetInfo {
                nodename: Some("i-should-probably-eat-lunch".to_string()),
                ..Default::default()
            })));
    }

    #[fuchsia_async::run_singlethreaded(test)]
    async fn test_target_collection_event_synthesis_none_connected() {
        let t = Target::new_named("clam-chowder-is-tasty");
        let t2 = Target::new_named("this-is-a-crunchy-falafel");
        let t3 = Target::new_named("i-should-probably-eat-lunch");
        let t4 = Target::new_named("i-should-probably-eat-lunch");

        let tc = TargetCollection::new_with_queue();
        tc.merge_insert(t);
        tc.merge_insert(t2);
        tc.merge_insert(t3);
        tc.merge_insert(t4);

        let events = tc.synthesize_events().await;
        assert_eq!(events.len(), 0);
    }

    struct EventPusher {
        got: async_channel::Sender<String>,
    }

    impl EventPusher {
        fn new() -> (Self, async_channel::Receiver<String>) {
            let (got, rx) = async_channel::unbounded::<String>();
            (Self { got }, rx)
        }
    }

    #[async_trait(?Send)]
    impl events::EventHandler<DaemonEvent> for EventPusher {
        async fn on_event(&self, event: DaemonEvent) -> Result<events::Status> {
            if let DaemonEvent::NewTarget(TargetInfo { nodename: Some(s), .. }) = event {
                self.got.send(s).await.unwrap();
                Ok(events::Status::Waiting)
            } else {
                panic!("this should never receive any other kind of event");
            }
        }
    }

    #[fuchsia_async::run_singlethreaded(test)]
    async fn test_target_collection_events() {
        let t = Target::new_named("clam-chowder-is-tasty");
        let t2 = Target::new_named("this-is-a-crunchy-falafel");
        let t3 = Target::new_named("i-should-probably-eat-lunch");

        let tc = Rc::new(TargetCollection::new());
        let queue = events::Queue::new(&tc);
        let (handler, rx) = EventPusher::new();
        queue.add_handler(handler).await;
        tc.set_event_queue(queue);
        tc.merge_insert(t);
        tc.merge_insert(t2);
        tc.merge_insert(t3);
        let results = rx.take(3).collect::<Vec<_>>().await;
        assert!(results.iter().any(|e| e == &"clam-chowder-is-tasty".to_string()));
        assert!(results.iter().any(|e| e == &"this-is-a-crunchy-falafel".to_string()));
        assert!(results.iter().any(|e| e == &"i-should-probably-eat-lunch".to_string()));
    }

    #[fuchsia_async::run_singlethreaded(test)]
    async fn test_target_wait_for_match() {
        let default = "clam-chowder-is-tasty";
        let t = Target::new_autoconnected(default);
        let t2 = Target::new_autoconnected("this-is-a-crunchy-falafel");
        let tc = TargetCollection::new_with_queue();
        tc.merge_insert(clone_target(&t));
        assert_eq!(tc.wait_for_match(Some(default.to_string())).await.unwrap(), t);
        assert_eq!(tc.wait_for_match(None).await.unwrap(), t);
        tc.merge_insert(t2);
        assert_eq!(tc.wait_for_match(Some(default.to_string())).await.unwrap(), t);
        assert!(tc.wait_for_match(None).await.is_err());
    }

    #[fuchsia_async::run_singlethreaded(test)]
    async fn test_target_wait_for_match_matches_contains() {
        let default = "clam-chowder-is-tasty";
        let t = Target::new_autoconnected(default);
        let t2 = Target::new_autoconnected("this-is-a-crunchy-falafel");
        let tc = TargetCollection::new_with_queue();
        tc.merge_insert(clone_target(&t));
        assert_eq!(tc.wait_for_match(Some(default.to_string())).await.unwrap(), t);
        assert_eq!(tc.wait_for_match(None).await.unwrap(), t);
        tc.merge_insert(t2);
        assert_eq!(tc.wait_for_match(Some(default.to_string())).await.unwrap(), t);
        assert!(tc.wait_for_match(None).await.is_err());
        assert_eq!(tc.wait_for_match(Some("clam".to_string())).await.unwrap(), t);
    }

    struct TargetUpdatedFut<F> {
        target_wait_fut: F,
        target_to_add: Rc<Target>,
        collection: Rc<TargetCollection>,
        target_wait_pending: bool,
    }

    /// This is a very specific future that does some things to force a specific state in the
    /// target collection.
    ///
    /// See the test below for the setup as an example.
    ///
    /// The preconditions are:
    /// 1. There is a target with a given address but no nodename in the target collection.
    /// 2. There is a future awaiting a target whose nodename will be added to the collection at a
    ///    later time.
    /// 3. The target we're going to add has the same address as the target already in the target
    ///    collection.
    ///
    /// The execution details are as follows when awaiting this future.
    /// 1. We poll the waiting for the target future until it is pending (flushing the NewTarget
    ///    events out of the event queue).
    /// 2. We add the new target with the matching addresses and nodename.
    /// 3. We await the future passed to this struct which was awaiting said nodename.
    ///
    /// This will succeed iff an UpdatedTarget event is pushed. Without this event this will hang
    /// indefinitely, because when we await a target by its nodename and we encounter the
    /// out-of-date target, we assume the match will never happen, and we wait for a new target
    /// event. The UpdatedTarget event forces the wait_for_target future to re-examine this updated
    /// target to see if it matches.
    impl<F> TargetUpdatedFut<F>
    where
        F: Future<Output = Rc<Target>> + std::marker::Unpin,
    {
        fn new(target_to_add: Rc<Target>, collection: Rc<TargetCollection>, fut: F) -> Self {
            Self { target_wait_fut: fut, target_to_add, collection, target_wait_pending: false }
        }
    }

    impl<F> Future for TargetUpdatedFut<F>
    where
        F: Future<Output = Rc<Target>> + std::marker::Unpin,
    {
        type Output = Rc<Target>;

        fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
            let target_wait_pending = self.target_wait_pending;
            let target_wait_fut = Pin::new(&mut self.target_wait_fut);
            if !target_wait_pending {
                // Flushes the NewTarget event here. Should panic if the target is found.
                match target_wait_fut.poll(cx) {
                    Poll::Ready(target) => {
                        panic!("Found named target when no nodename was included. This should not happen: {:?}", target);
                    }
                    Poll::Pending => {
                        // Once the event has been flushed, inserting a new target will queue up
                        // the UpdatedTarget event.
                        self.target_wait_pending = true;
                        self.collection.merge_insert(self.target_to_add.clone());
                    }
                }
                Poll::Pending
            } else {
                target_wait_fut.poll(cx)
            }
        }
    }

    #[fuchsia_async::run_singlethreaded(test)]
    async fn test_target_wait_for_match_updated_target() {
        let address = "f111::1";
        let ip = address.parse().unwrap();
        let mut addr_set = BTreeSet::new();
        addr_set.replace(TargetAddr::from((ip, 0)));
        let t = Target::new_with_addrs(Option::<String>::None, addr_set);
        let tc = TargetCollection::new_with_queue();
        tc.merge_insert(t);
        let target_name = "fesenjoon-is-my-jam";
        let wait_fut =
            Box::pin(async { tc.wait_for_match(Some(target_name.to_string())).await.unwrap() });
        // Now we will update the target with a nodename. This should merge into
        // the collection and create an updated target event.
        let t2 = Target::new_autoconnected(target_name);
        t2.addrs.borrow_mut().replace(TargetAddrEntry::new(
            TargetAddr::from((ip, 0)),
            Utc::now(),
            TargetAddrType::Ssh,
        ));
        let fut = TargetUpdatedFut::new(clone_target(&t2), tc.clone(), wait_fut);
        assert_eq!(fut.await, t2);
    }

    #[fuchsia_async::run_singlethreaded(test)]
    async fn test_target_merge_no_name() {
        let ip = "f111::3".parse().unwrap();

        // t1 is a target as we would naturally discover it via mdns, or from a
        // user adding it explicitly. That is, the target has a correctly scoped
        // link-local address.
        let mut addr_set = BTreeSet::new();
        addr_set.replace(TargetAddr::from((ip, 0xbadf00d)));
        let t1 = Target::new_with_addrs(Option::<String>::None, addr_set);

        // t2 is an incoming target that has the same address, but, it is
        // missing scope information, this is essentially what occurs when we
        // ask the target for its addresses.
        let t2 = Target::new_named("this-is-a-crunchy-falafel");
        t2.addrs.borrow_mut().replace(TargetAddrEntry::new(
            TargetAddr::from((ip, 0)),
            Utc::now(),
            TargetAddrType::Ssh,
        ));

        let tc = TargetCollection::new_with_queue();
        tc.merge_insert(t1);
        tc.merge_insert(t2);
        let mut targets = tc.targets().into_iter();
        let target = targets.next().expect("Merging resulted in no targets.");
        assert!(targets.next().is_none());
        assert_eq!(target.nodename_str(), "this-is-a-crunchy-falafel");
        let mut addrs = target.addrs().into_iter();
        let addr = addrs.next().expect("Merged target has no address.");
        assert!(addrs.next().is_none());
        assert_eq!(addr, TargetAddr::from((ip, 0xbadf00d)));
        assert_eq!(addr.ip(), ip);
        assert_eq!(addr.scope_id(), 0xbadf00d);
    }

    #[fuchsia_async::run_singlethreaded(test)]
    async fn test_target_does_not_merge_different_ports_with_no_name() {
        let ip = "fe80::1".parse().unwrap();

        let mut addr_set = BTreeSet::new();
        addr_set.replace(TargetAddr::from((ip, 1)));
        let t1 = Target::new_with_addrs(Option::<String>::None, addr_set.clone());
        t1.set_ssh_port(Some(8022));
        let t2 = Target::new_with_addrs(Option::<String>::None, addr_set.clone());
        t2.set_ssh_port(Some(8023));

        let tc = TargetCollection::new_with_queue();
        tc.merge_insert(t1);
        tc.merge_insert(t2);

        let mut targets = tc.targets().into_iter().collect::<Vec<Rc<Target>>>();

        assert_eq!(targets.len(), 2);

        targets.sort_by(|a, b| a.ssh_port().cmp(&b.ssh_port()));
        let mut iter = targets.into_iter();
        let mut found1 = iter.next().expect("must have target one");
        let mut found2 = iter.next().expect("must have target two");

        // Avoid iterator order dependency
        if found1.ssh_port() == Some(8023) {
            std::mem::swap(&mut found1, &mut found2)
        }

        assert_eq!(found1.addrs().into_iter().next().unwrap().ip(), ip);
        assert_eq!(found1.ssh_port(), Some(8022));

        assert_eq!(found2.addrs().into_iter().next().unwrap().ip(), ip);
        assert_eq!(found2.ssh_port(), Some(8023));
    }

    #[fuchsia_async::run_singlethreaded(test)]
    async fn test_target_does_not_merge_different_ports() {
        let ip = "fe80::1".parse().unwrap();

        let mut addr_set = BTreeSet::new();
        addr_set.replace(TargetAddr::from((ip, 1)));
        let t1 = Target::new_with_addrs(Some("t1"), addr_set.clone());
        t1.set_ssh_port(Some(8022));
        let t2 = Target::new_with_addrs(Some("t2"), addr_set.clone());
        t2.set_ssh_port(Some(8023));

        let tc = TargetCollection::new_with_queue();
        tc.merge_insert(t1);
        tc.merge_insert(t2);

        let mut targets = tc.targets().into_iter().collect::<Vec<Rc<Target>>>();

        assert_eq!(targets.len(), 2);

        targets.sort_by(|a, b| a.ssh_port().cmp(&b.ssh_port()));
        let mut iter = targets.into_iter();
        let found1 = iter.next().expect("must have target one");
        let found2 = iter.next().expect("must have target two");

        assert_eq!(found1.addrs().into_iter().next().unwrap().ip(), ip);
        assert_eq!(found1.ssh_port(), Some(8022));
        assert_eq!(found1.nodename(), Some("t1".to_string()));

        assert_eq!(found2.addrs().into_iter().next().unwrap().ip(), ip);
        assert_eq!(found2.ssh_port(), Some(8023));
        assert_eq!(found2.nodename(), Some("t2".to_string()));
    }

    #[fuchsia_async::run_singlethreaded(test)]
    async fn test_target_wait_for_match_successful() {
        let default = "clam-chowder-is-tasty";
        let t = Target::new_autoconnected(default);
        let tc = TargetCollection::new_with_queue();
        tc.merge_insert(clone_target(&t));
        assert_eq!(tc.wait_for_match(Some(default.to_string())).await.unwrap(), t);
    }

    #[fuchsia_async::run_singlethreaded(test)]
    async fn test_target_wait_for_match_ambiguous() {
        let default = "clam-chowder-is-tasty";
        let t = Target::new_autoconnected(default);
        let t2 = Target::new_autoconnected("this-is-a-crunchy-falafel");
        let tc = TargetCollection::new_with_queue();
        tc.merge_insert(clone_target(&t));
        tc.merge_insert(t2);
        assert_eq!(Err(DaemonError::TargetAmbiguous), tc.wait_for_match(None).await);
    }

    #[fuchsia_async::run_singlethreaded(test)]
    async fn test_target_remove_unnamed_by_addr() {
        let ip1 = "f111::3".parse().unwrap();
        let ip2 = "f111::4".parse().unwrap();
        let mut addr_set = BTreeSet::new();
        addr_set.replace(TargetAddr::from((ip1, 0xbadf00d)));
        let t1 = Target::new_with_addrs::<String>(None, addr_set);
        let t2 = Target::new_named("this-is-a-crunchy-falafel");
        let tc = TargetCollection::new_with_queue();
        t2.addrs.borrow_mut().replace(TargetAddr::from((ip2, 0)).into());
        tc.merge_insert(t1);
        tc.merge_insert(t2);
        let mut targets = tc.targets().into_iter();
        let mut target1 = targets.next().expect("Merging resulted in no targets.");
        let mut target2 = targets.next().expect("Merging resulted in only one target.");

        if target1.nodename().is_none() {
            std::mem::swap(&mut target1, &mut target2)
        }

        assert!(targets.next().is_none());
        assert_eq!(target1.nodename_str(), "this-is-a-crunchy-falafel");
        assert_eq!(target2.nodename(), None);
        assert!(tc.remove_target("f111::3".to_owned()));
        let mut targets = tc.targets().into_iter();
        let target = targets.next().expect("Merging resulted in no targets.");
        assert!(targets.next().is_none());
        assert_eq!(target.nodename_str(), "this-is-a-crunchy-falafel");
    }

    #[fuchsia_async::run_singlethreaded(test)]
    async fn test_target_remove_named_by_addr() {
        let ip1 = "f111::3".parse().unwrap();
        let ip2 = "f111::4".parse().unwrap();
        let mut addr_set = BTreeSet::new();
        addr_set.replace(TargetAddr::from((ip1, 0xbadf00d)));
        let t1 = Target::new_with_addrs::<String>(None, addr_set);
        let t2 = Target::new_named("this-is-a-crunchy-falafel");
        let tc = TargetCollection::new_with_queue();
        t2.addrs.borrow_mut().replace(TargetAddr::from((ip2, 0)).into());
        tc.merge_insert(t1);
        tc.merge_insert(t2);
        let mut targets = tc.targets().into_iter();
        let mut target1 = targets.next().expect("Merging resulted in no targets.");
        let mut target2 = targets.next().expect("Merging resulted in only one target.");

        if target1.nodename().is_none() {
            std::mem::swap(&mut target1, &mut target2);
        }
        assert!(targets.next().is_none());
        assert_eq!(target1.nodename_str(), "this-is-a-crunchy-falafel");
        assert_eq!(target2.nodename(), None);
        assert!(tc.remove_target("f111::4".to_owned()));
        let mut targets = tc.targets().into_iter();
        let target = targets.next().expect("Merging resulted in no targets.");
        assert!(targets.next().is_none());
        assert_eq!(target.nodename(), None);
    }

    #[fuchsia_async::run_singlethreaded(test)]
    async fn test_target_remove_by_name() {
        let ip1 = "f111::3".parse().unwrap();
        let ip2 = "f111::4".parse().unwrap();
        let mut addr_set = BTreeSet::new();
        addr_set.replace(TargetAddr::from((ip1, 0xbadf00d)));
        let t1 = Target::new_with_addrs::<String>(None, addr_set);
        let t2 = Target::new_named("this-is-a-crunchy-falafel");
        let tc = TargetCollection::new_with_queue();
        t2.addrs.borrow_mut().replace(TargetAddr::from((ip2, 0)).into());
        tc.merge_insert(t1);
        tc.merge_insert(t2);
        let mut targets = tc.targets().into_iter();
        let mut target1 = targets.next().expect("Merging resulted in no targets.");
        let mut target2 = targets.next().expect("Merging resulted in only one target.");

        if target1.nodename().is_none() {
            std::mem::swap(&mut target1, &mut target2);
        }

        assert!(targets.next().is_none());
        assert_eq!(target1.nodename_str(), "this-is-a-crunchy-falafel");
        assert_eq!(target2.nodename(), None);
        assert!(tc.remove_target("this-is-a-crunchy-falafel".to_owned()));
        let mut targets = tc.targets().into_iter();
        let target = targets.next().expect("Merging resulted in no targets.");
        assert!(targets.next().is_none());
        assert_eq!(target.nodename(), None);
    }

    #[test]
    fn test_collection_removal_disconnects_target() {
        let target = Target::new_named("soggy-falafel");
        target.set_state(TargetConnectionState::Mdns(Instant::now()));
        target.host_pipe.borrow_mut().replace(Task::local(future::pending()));

        let collection = TargetCollection::new();
        collection.merge_insert(target.clone());
        collection.remove_target("soggy-falafel".to_owned());

        assert_eq!(target.get_connection_state(), TargetConnectionState::Disconnected);
        assert!(target.host_pipe.borrow().is_none());
    }

    #[fuchsia_async::run_singlethreaded(test)]
    async fn test_target_match_serial() {
        let string = "turritopsis-dohrnii-is-an-immortal-jellyfish";
        let t = Target::new_with_serial(string);
        let tc = TargetCollection::new_with_queue();
        tc.merge_insert(clone_target(&t));
        let found_target = tc.get(string).expect("target serial should match");
        assert_eq!(string, found_target.serial().expect("target should have serial number"));
        assert!(found_target.nodename().is_none());
    }

    #[fuchsia_async::run_singlethreaded(test)]
    async fn test_no_ambiguous_target_when_disconnected() {
        // While this is an implementation detail, the naming of these targets
        // are important. The match order of the targets, if not filtering by
        // whether they are connected, is such that the disconnected target
        // would come first. With filtering, though, the "this-is-connected"
        // target would be found.
        let t = Target::new_autoconnected("this-is-connected");
        let t2 = Target::new_named("this-is-not-connected");
        let tc = TargetCollection::new_with_queue();
        tc.merge_insert(clone_target(&t2));
        tc.merge_insert(clone_target(&t));
        let found_target = tc.wait_for_match(None).await.expect("should match");
        assert_eq!(
            "this-is-connected",
            found_target.nodename().expect("target should have nodename")
        );
        let found_target =
            tc.wait_for_match(Some("connected".to_owned())).await.expect("should match");
        assert_eq!(
            "this-is-connected",
            found_target.nodename().expect("target should have nodename")
        );
    }

    #[fuchsia_async::run_singlethreaded(test)]
    async fn test_target_query_matches_nodename() {
        let query = TargetQuery::from("foo");
        let target = Rc::new(Target::new_named("foo"));
        assert!(query.matches(&target));
    }

    #[test]
    fn test_target_query_from_socketaddr_both_zero_port() {
        let tq = TargetQuery::from("127.0.0.1:0");
        let ti = TargetInfo {
            addresses: vec![("127.0.0.1".parse::<IpAddr>().unwrap(), 0).into()],
            ssh_port: None,
            ..Default::default()
        };
        assert!(
            matches!(tq, TargetQuery::AddrPort((addr, port)) if addr == ti.addresses[0] && None == ti.ssh_port && port == 0)
        );
        assert!(tq.match_info(&ti));
    }

    #[test]
    fn test_target_query_from_socketaddr_zero_port_to_standard_ssh_port_fails() {
        let tq = TargetQuery::from("127.0.0.1:0");
        let ti = TargetInfo {
            addresses: vec![("127.0.0.1".parse::<IpAddr>().unwrap(), 0).into()],
            ssh_port: Some(22),
            ..Default::default()
        };
        assert!(
            matches!(tq, TargetQuery::AddrPort((addr, port)) if addr == ti.addresses[0] && Some(22) == ti.ssh_port && port == 0)
        );
        assert!(!tq.match_info(&ti));
    }

    #[test]
    fn test_target_query_from_socketaddr_standard_port_to_no_port() {
        let tq = TargetQuery::from("127.0.0.1:22");
        let ti = TargetInfo {
            addresses: vec![("127.0.0.1".parse::<IpAddr>().unwrap(), 0).into()],
            ssh_port: None,
            ..Default::default()
        };
        assert!(
            matches!(tq, TargetQuery::AddrPort((addr, port)) if addr == ti.addresses[0] && None == ti.ssh_port && port == 22)
        );
        assert!(tq.match_info(&ti));
    }

    #[test]
    fn test_target_query_from_socketaddr_both_standard_port() {
        let tq = TargetQuery::from("127.0.0.1:22");
        let ti = TargetInfo {
            addresses: vec![("127.0.0.1".parse::<IpAddr>().unwrap(), 0).into()],
            ssh_port: Some(22),
            ..Default::default()
        };
        assert!(
            matches!(tq, TargetQuery::AddrPort((addr, port)) if addr == ti.addresses[0] && Some(22) == ti.ssh_port && port == 22)
        );
        assert!(tq.match_info(&ti));
    }

    #[test]
    fn test_target_query_from_socketaddr_random_port_no_target_port_fails() {
        let tq = TargetQuery::from("127.0.0.1:2342");
        let ti = TargetInfo {
            addresses: vec![("127.0.0.1".parse::<IpAddr>().unwrap(), 0).into()],
            ssh_port: None,
            ..Default::default()
        };
        assert!(
            matches!(tq, TargetQuery::AddrPort((addr, port)) if addr == ti.addresses[0] && None == ti.ssh_port && port == 2342)
        );
        assert!(!tq.match_info(&ti));
    }

    #[test]
    fn test_target_query_from_socketaddr_zero_port_to_random_target_port_fails() {
        let tq = TargetQuery::from("127.0.0.1:0");
        let ti = TargetInfo {
            addresses: vec![("127.0.0.1".parse::<IpAddr>().unwrap(), 0).into()],
            ssh_port: Some(2223),
            ..Default::default()
        };
        assert!(
            matches!(tq, TargetQuery::AddrPort((addr, port)) if addr == ti.addresses[0] && Some(2223) == ti.ssh_port && port == 0)
        );
        assert!(!tq.match_info(&ti));
    }

    #[test]
    fn test_target_query_from_sockaddr() {
        let tq = TargetQuery::from("127.0.0.1:8022");
        let ti = TargetInfo {
            addresses: vec![("127.0.0.1".parse::<IpAddr>().unwrap(), 0).into()],
            ssh_port: Some(8022),
            ..Default::default()
        };
        assert!(
            matches!(tq, TargetQuery::AddrPort((addr, port)) if addr == ti.addresses[0] && Some(port) == ti.ssh_port)
        );
        assert!(tq.match_info(&ti));

        let tq = TargetQuery::from("[::1]:8022");
        let ti = TargetInfo {
            addresses: vec![("::1".parse::<IpAddr>().unwrap(), 0).into()],
            ssh_port: Some(8022),
            ..Default::default()
        };
        assert!(
            matches!(tq, TargetQuery::AddrPort((addr, port)) if addr == ti.addresses[0] && Some(port) == ti.ssh_port)
        );
        assert!(tq.match_info(&ti));

        let tq = TargetQuery::from("[::1]");
        let ti = TargetInfo {
            addresses: vec![("::1".parse::<IpAddr>().unwrap(), 0).into()],
            ssh_port: None,
            ..Default::default()
        };
        assert!(matches!(tq, TargetQuery::Addr(addr) if addr == ti.addresses[0]));
        assert!(tq.match_info(&ti));

        let tq = TargetQuery::from("[fe80::1]:22");
        let ti = TargetInfo {
            addresses: vec![("fe80::1".parse::<IpAddr>().unwrap(), 0).into()],
            ssh_port: Some(22),
            ..Default::default()
        };
        assert!(
            matches!(tq, TargetQuery::AddrPort((addr, port)) if addr == ti.addresses[0] && Some(port) == ti.ssh_port)
        );
        assert!(tq.match_info(&ti));

        let tq = TargetQuery::from("192.168.0.1:22");
        let ti = TargetInfo {
            addresses: vec![("192.168.0.1".parse::<IpAddr>().unwrap(), 0).into()],
            ssh_port: Some(22),
            ..Default::default()
        };
        assert!(
            matches!(tq, TargetQuery::AddrPort((addr, port)) if addr == ti.addresses[0] && Some(port) == ti.ssh_port)
        );
        assert!(tq.match_info(&ti));

        // Note: socketaddr only supports numeric scopes
        let tq = TargetQuery::from("[fe80::1%1]:22");
        let ti = TargetInfo {
            addresses: vec![("fe80::1".parse::<IpAddr>().unwrap(), 1).into()],
            ssh_port: Some(22),
            ..Default::default()
        };
        assert!(
            matches!(tq, TargetQuery::AddrPort((addr, port)) if addr == ti.addresses[0] && Some(port) == ti.ssh_port)
        );
        assert!(tq.match_info(&ti));
    }

    #[test]
    fn test_target_query_from_empty_string() {
        let query = TargetQuery::from(Some(""));
        assert!(matches!(query, TargetQuery::First));
    }

    #[test]
    fn test_target_query_with_no_scope_matches_scoped_target_info() {
        let addr: TargetAddr =
            (IpAddr::from([0xfe80, 0x0, 0x0, 0x0, 0xdead, 0xbeef, 0xbeef, 0xbeef]), 3).into();
        let tq = TargetQuery::from("fe80::dead:beef:beef:beef");
        assert!(tq.match_info(&TargetInfo { addresses: vec![addr], ..Default::default() }))
    }
}
