// Copyright 2020 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.

#![deny(missing_docs, unreachable_patterns)]

//! Netemul utilities.

use std::convert::TryInto as _;
use std::path::{Path, PathBuf};

use fidl_fuchsia_hardware_ethernet as hw_eth;
use fidl_fuchsia_hardware_network as hw_net;
use fidl_fuchsia_net as net;
use fidl_fuchsia_net_dhcp as net_dhcp;
use fidl_fuchsia_net_interfaces as net_interfaces;
use fidl_fuchsia_net_stack as net_stack;
use fidl_fuchsia_net_stack_ext::FidlReturn as _;
use fidl_fuchsia_netemul_environment as netemul_environment;
use fidl_fuchsia_netemul_network as netemul_network;
use fidl_fuchsia_netemul_sandbox as netemul_sandbox;
use fidl_fuchsia_netstack as netstack;
use fidl_fuchsia_posix_socket as posix_socket;
use fidl_fuchsia_sys as sys;
use fuchsia_zircon as zx;

use anyhow::Context as _;
use futures::future::{FutureExt as _, TryFutureExt as _};

type Result<T = ()> = std::result::Result<T, anyhow::Error>;

/// The default MTU used in in netemul endpoint configurations.
pub const DEFAULT_MTU: u16 = 1500;

/// Abstraction for different endpoint backing types.
pub trait Endpoint: Copy + Clone {
    /// The backing [`EndpointBacking`] for this `Endpoint`.
    ///
    /// [`EndpointBacking`]: netemul_network::EndpointBacking
    const NETEMUL_BACKING: netemul_network::EndpointBacking;

    /// The relative path from the root device directory where devices of this `Endpoint`
    /// can be discovered.
    const DEV_PATH: &'static str;

    /// Returns the path to an endpoint with the given name in this `Endpoint`'s
    /// device directory.
    fn dev_path(name: &str) -> PathBuf {
        Path::new(Self::DEV_PATH).join(name)
    }

    /// Returns an [`EndpointConfig`] with the provided parameters for this
    /// endpoint type.
    ///
    /// [`EndpointConfig`]: netemul_network::EndpointConfig
    fn make_config(mtu: u16, mac: Option<net::MacAddress>) -> netemul_network::EndpointConfig {
        netemul_network::EndpointConfig {
            mtu,
            mac: mac.map(Box::new),
            backing: Self::NETEMUL_BACKING,
        }
    }
}

/// An Ethernet implementation of `Endpoint`.
#[derive(Copy, Clone)]
pub enum Ethernet {}

impl Endpoint for Ethernet {
    const NETEMUL_BACKING: netemul_network::EndpointBacking =
        netemul_network::EndpointBacking::Ethertap;
    const DEV_PATH: &'static str = "class/ethernet";
}

/// A Network Device implementation of `Endpoint`.
#[derive(Copy, Clone)]
pub enum NetworkDevice {}

impl Endpoint for NetworkDevice {
    const NETEMUL_BACKING: netemul_network::EndpointBacking =
        netemul_network::EndpointBacking::NetworkDevice;
    const DEV_PATH: &'static str = "class/network";
}

/// Helper definition to help type system identify `None` as `IntoIterator`
/// where `Item: Into<netemul_environment::LaunchService`.
pub const NO_SERVICES: Option<netemul_environment::LaunchService> = None;

/// A test sandbox backed by a [`netemul_sandbox::SandboxProxy`].
///
/// `TestSandbox` provides various utility methods to set up network
/// environments for use in testing. The lifetime of the `TestSandbox` is tied
/// to the netemul sandbox itself, dropping it will cause all the created
/// environments, networks, and endpoints to be destroyed.
#[must_use]
pub struct TestSandbox {
    sandbox: netemul_sandbox::SandboxProxy,
}

impl TestSandbox {
    /// Creates a new empty sandbox.
    pub fn new() -> Result<TestSandbox> {
        let sandbox =
            fuchsia_component::client::connect_to_service::<netemul_sandbox::SandboxMarker>()
                .context("failed to connect to sandbox service")?;
        Ok(TestSandbox { sandbox })
    }

    /// Creates an environment with `name` and `services`.
    pub fn create_environment<I>(
        &self,
        name: impl Into<String>,
        services: I,
    ) -> Result<TestEnvironment<'_>>
    where
        I: IntoIterator,
        I::Item: Into<netemul_environment::LaunchService>,
    {
        let (environment, server) =
            fidl::endpoints::create_proxy::<netemul_environment::ManagedEnvironmentMarker>()?;
        let name = name.into();
        let () = self.sandbox.create_environment(
            server,
            netemul_environment::EnvironmentOptions {
                name: Some(name.clone()),
                services: Some(services.into_iter().map(Into::into).collect()),
                devices: None,
                inherit_parent_launch_services: None,
                logger_options: Some(netemul_environment::LoggerOptions {
                    enabled: Some(true),
                    klogs_enabled: None,
                    filter_options: None,
                    syslog_output: Some(true),
                    ..netemul_environment::LoggerOptions::EMPTY
                }),
                ..netemul_environment::EnvironmentOptions::EMPTY
            },
        )?;
        Ok(TestEnvironment { environment, name, _sandbox: self })
    }

    /// Creates an environment with no services.
    pub fn create_empty_environment(&self, name: impl Into<String>) -> Result<TestEnvironment<'_>> {
        self.create_environment(name, NO_SERVICES)
    }

    /// Connects to the sandbox's `NetworkContext`.
    fn get_network_context(&self) -> Result<netemul_network::NetworkContextProxy> {
        let (ctx, server) =
            fidl::endpoints::create_proxy::<netemul_network::NetworkContextMarker>()?;
        let () = self.sandbox.get_network_context(server)?;
        Ok(ctx)
    }

    /// Connects to the sandbox's `NetworkManager`.
    fn get_network_manager(&self) -> Result<netemul_network::NetworkManagerProxy> {
        let ctx = self.get_network_context()?;
        let (network_manager, server) =
            fidl::endpoints::create_proxy::<netemul_network::NetworkManagerMarker>()?;
        let () = ctx.get_network_manager(server)?;
        Ok(network_manager)
    }

    /// Connects to the sandbox's `EndpointManager`.
    fn get_endpoint_manager(&self) -> Result<netemul_network::EndpointManagerProxy> {
        let ctx = self.get_network_context()?;
        let (ep_manager, server) =
            fidl::endpoints::create_proxy::<netemul_network::EndpointManagerMarker>()?;
        let () = ctx.get_endpoint_manager(server)?;
        Ok(ep_manager)
    }

    /// Creates a new empty network with default configurations and `name`.
    pub async fn create_network(&self, name: impl Into<String>) -> Result<TestNetwork<'_>> {
        let name = name.into();
        let netm = self.get_network_manager()?;
        let (status, network) = netm
            .create_network(
                &name,
                netemul_network::NetworkConfig {
                    latency: None,
                    packet_loss: None,
                    reorder: None,
                    ..netemul_network::NetworkConfig::EMPTY
                },
            )
            .await
            .context("create_network FIDL error")?;
        let () = zx::Status::ok(status).context("create_network failed")?;
        let network = network
            .ok_or_else(|| anyhow::anyhow!("create_network didn't return a valid network"))?
            .into_proxy()?;
        Ok(TestNetwork { network, name, sandbox: self })
    }

    /// Creates a new unattached endpoint with default configurations and `name`.
    pub async fn create_endpoint<E, S>(&self, name: S) -> Result<TestEndpoint<'_>>
    where
        S: Into<String>,
        E: Endpoint,
    {
        self.create_endpoint_with(name, E::make_config(DEFAULT_MTU, None)).await
    }

    /// Creates a new unattached endpoint with the provided configuration.
    pub async fn create_endpoint_with(
        &self,
        name: impl Into<String>,
        mut config: netemul_network::EndpointConfig,
    ) -> Result<TestEndpoint<'_>> {
        let name = name.into();
        let epm = self.get_endpoint_manager()?;
        let (status, endpoint) =
            epm.create_endpoint(&name, &mut config).await.context("create_endpoint FIDL error")?;
        let () = zx::Status::ok(status).context("create_endpoint failed")?;
        let endpoint = endpoint
            .ok_or_else(|| anyhow::anyhow!("create_endpoint didn't return a valid endpoint"))?
            .into_proxy()?;
        Ok(TestEndpoint { endpoint, name, _sandbox: self })
    }
}

/// Interface configuration used by [`TestEnvironment::join_network`].
pub enum InterfaceConfig {
    /// Interface is configured with a static address.
    StaticIp(net::Subnet),
    /// Interface is configured to use DHCP to obtain an address.
    Dhcp,
    /// No address configuration is performed.
    None,
}

/// An environment within a netemul sandbox.
#[must_use]
pub struct TestEnvironment<'a> {
    environment: netemul_environment::ManagedEnvironmentProxy,
    name: String,
    _sandbox: &'a TestSandbox,
}

impl<'a> TestEnvironment<'a> {
    /// Connects to a service within the environment.
    pub fn connect_to_service<S>(&self) -> Result<S::Proxy>
    where
        S: fidl::endpoints::ServiceMarker + fidl::endpoints::DiscoverableService,
    {
        let (proxy, server) = zx::Channel::create()?;
        let () = self.environment.connect_to_service(S::SERVICE_NAME, server)?;
        let proxy = fuchsia_async::Channel::from_channel(proxy)?;
        Ok(<S::Proxy as fidl::endpoints::Proxy>::from_channel(proxy))
    }

    /// Gets this environment's launcher.
    ///
    /// All applications launched within a netemul environment will have their
    /// output (stdout, stderr, syslog) decorated with the environment name.
    pub fn get_launcher(&self) -> Result<sys::LauncherProxy> {
        let (launcher, server) = fidl::endpoints::create_proxy::<sys::LauncherMarker>()
            .context("failed to create launcher proxy")?;
        let () = self.environment.get_launcher(server)?;
        Ok(launcher)
    }

    /// Like [`join_network_with`], but uses default endpoint configurations.
    pub async fn join_network<E, S>(
        &self,
        network: &TestNetwork<'a>,
        ep_name: S,
        config: &InterfaceConfig,
    ) -> Result<TestInterface<'a>>
    where
        E: Endpoint,
        S: Into<String>,
    {
        let endpoint =
            network.create_endpoint::<E, _>(ep_name).await.context("failed to create endpoint")?;
        self.install_endpoint(endpoint, config).await
    }

    /// Joins `network` with by creating an endpoint with `ep_config` and
    /// installing it into the environment with `if_config`.
    ///
    /// `join_network_with` is a helper to create a new endpoint `ep_name`
    /// attached to `network` and configure it with `if_config`. Returns a
    /// [`TestInterface`] which is already added to this environment's netstack,
    /// link online, enabled, and configured according to `config`.
    ///
    /// Note that this environment needs a Netstack for this operation to
    /// succeed.
    pub async fn join_network_with(
        &self,
        network: &TestNetwork<'a>,
        ep_name: impl Into<String>,
        ep_config: netemul_network::EndpointConfig,
        if_config: &InterfaceConfig,
    ) -> Result<TestInterface<'a>> {
        let endpoint = network
            .create_endpoint_with(ep_name, ep_config)
            .await
            .context("failed to create endpoint")?;
        self.install_endpoint(endpoint, if_config).await
    }

    /// Installs and configures `endpoint` in this environment with `config`.
    pub async fn install_endpoint(
        &self,
        endpoint: TestEndpoint<'a>,
        config: &InterfaceConfig,
    ) -> Result<TestInterface<'a>> {
        let interface =
            endpoint.into_interface_in_environment(self).await.context("failed to add endpoint")?;
        let () = interface.set_link_up(true).await.context("failed to start endpoint")?;
        let () = match config {
            InterfaceConfig::StaticIp(addr) => {
                interface.add_ip_addr(*addr).await.context("failed to add static IP")?
            }
            InterfaceConfig::Dhcp => {
                interface.start_dhcp().await.context("failed to start DHCP")?;
            }
            InterfaceConfig::None => (),
        };
        let () = interface.enable_interface().await.context("failed to enable interface")?;

        // Wait for Netstack to observe interface up so callers can safely
        // assume the state of the world on return.
        let interface_state = self
            .connect_to_service::<net_interfaces::StateMarker>()
            .context("failed to connect to fuchsia.net.interfaces/State")?;
        let () = fidl_fuchsia_net_interfaces_ext::wait_interface_with_id(
            fidl_fuchsia_net_interfaces_ext::event_stream_from_state(&interface_state)?,
            &mut fidl_fuchsia_net_interfaces_ext::InterfaceState::Unknown(interface.id()),
            |&fidl_fuchsia_net_interfaces_ext::Properties { online, .. }| {
                // TODO(https://github.com/rust-lang/rust/issues/80967): use bool::then_some.
                online.then(|| ())
            },
        )
        .await
        .context("failed to observe interface up")?;

        Ok(interface)
    }

    /// Adds a device to the environment's virtual device filesystem.
    pub fn add_virtual_device(&self, e: &TestEndpoint<'_>, path: &Path) -> Result {
        let path = path
            .to_str()
            .with_context(|| format!("convert {} to str", path.display()))?
            .to_string();
        let (device, device_server_end) =
            fidl::endpoints::create_endpoints::<netemul_network::DeviceProxy_Marker>()
                .context("create endpoints")?;
        e.get_proxy_(device_server_end).context("get proxy")?;

        self.environment
            .add_device(&mut netemul_environment::VirtualDevice { path, device })
            .context("add device")
    }

    /// Removes a device from the environment's virtual device filesystem.
    pub fn remove_virtual_device(&self, path: &Path) -> Result {
        let path = path.to_str().with_context(|| format!("convert {} to str", path.display()))?;
        self.environment.remove_device(path).context("remove device")
    }

    /// Creates a Datagram [`socket2::Socket`] backed by the implementation of
    /// `fuchsia.posix.socket/Provider` in this environment.
    pub async fn datagram_socket(
        &self,
        domain: fidl_fuchsia_posix_socket::Domain,
        proto: fidl_fuchsia_posix_socket::DatagramSocketProtocol,
    ) -> Result<socket2::Socket> {
        let socket_provider = self
            .connect_to_service::<posix_socket::ProviderMarker>()
            .context("failed to connect to socket provider")?;
        let sock = socket_provider
            .datagram_socket(domain, proto)
            .await
            .context("failed to call socket")?
            .map_err(|e| std::io::Error::from_raw_os_error(e.into_primitive()))
            .context("failed to create socket")?;

        Ok(fdio::create_fd(sock.into()).context("failed to create fd")?)
    }

    /// Creates a Stream [`socket2::Socket`] backed by the implementation of
    /// `fuchsia.posix.socket/Provider` in this environment.
    pub async fn stream_socket(
        &self,
        domain: fidl_fuchsia_posix_socket::Domain,
        proto: fidl_fuchsia_posix_socket::StreamSocketProtocol,
    ) -> Result<socket2::Socket> {
        let socket_provider = self
            .connect_to_service::<posix_socket::ProviderMarker>()
            .context("failed to connect to socket provider")?;
        let sock = socket_provider
            .stream_socket(domain, proto)
            .await
            .context("failed to call socket")?
            .map_err(|e| std::io::Error::from_raw_os_error(e.into_primitive()))
            .context("failed to create socket")?;

        Ok(fdio::create_fd(sock.into()).context("failed to create fd")?)
    }
}

/// A virtual Network.
///
/// `TestNetwork` is a single virtual broadcast domain backed by Netemul.
/// Created through [`TestSandbox::create_network`].
#[must_use]
pub struct TestNetwork<'a> {
    network: netemul_network::NetworkProxy,
    name: String,
    sandbox: &'a TestSandbox,
}

impl<'a> TestNetwork<'a> {
    /// Attaches `ep` to this network.
    pub async fn attach_endpoint(&self, ep: &TestEndpoint<'a>) -> Result<()> {
        let status =
            self.network.attach_endpoint(&ep.name).await.context("attach_endpoint FIDL error")?;
        let () = zx::Status::ok(status).context("attach_endpoint failed")?;
        Ok(())
    }

    /// Creates a new endpoint with `name` attached to this network.
    pub async fn create_endpoint<E, S>(&self, name: S) -> Result<TestEndpoint<'a>>
    where
        E: Endpoint,
        S: Into<String>,
    {
        let ep = self
            .sandbox
            .create_endpoint::<E, _>(name)
            .await
            .with_context(|| format!("failed to create endpoint for network {}", self.name))?;
        let () = self.attach_endpoint(&ep).await.with_context(|| {
            format!("failed to attach endpoint {} to network {}", ep.name, self.name)
        })?;
        Ok(ep)
    }

    /// Creates a new endpoint with `name` and `config` attached to this
    /// network.
    pub async fn create_endpoint_with(
        &self,
        name: impl Into<String>,
        config: netemul_network::EndpointConfig,
    ) -> Result<TestEndpoint<'a>> {
        let ep = self
            .sandbox
            .create_endpoint_with(name, config)
            .await
            .with_context(|| format!("failed to create endpoint for network {}", self.name))?;
        let () = self.attach_endpoint(&ep).await.with_context(|| {
            format!("failed to attach endpoint {} to network {}", ep.name, self.name)
        })?;
        Ok(ep)
    }

    /// Returns a fake endpoint.
    pub fn create_fake_endpoint(&self) -> Result<TestFakeEndpoint<'a>> {
        let (endpoint, server) =
            fidl::endpoints::create_proxy::<netemul_network::FakeEndpointMarker>()
                .context("failed to create launcher proxy")?;
        let () = self.network.create_fake_endpoint(server)?;
        return Ok(TestFakeEndpoint { endpoint, _sandbox: self.sandbox });
    }
}

/// A virtual network endpoint backed by Netemul.
#[must_use]
pub struct TestEndpoint<'a> {
    endpoint: netemul_network::EndpointProxy,
    name: String,
    _sandbox: &'a TestSandbox,
}

impl<'a> std::ops::Deref for TestEndpoint<'a> {
    type Target = netemul_network::EndpointProxy;

    fn deref(&self) -> &Self::Target {
        &self.endpoint
    }
}

/// A virtual fake network endpoint backed by Netemul.
#[must_use]
pub struct TestFakeEndpoint<'a> {
    endpoint: netemul_network::FakeEndpointProxy,
    _sandbox: &'a TestSandbox,
}

impl<'a> std::ops::Deref for TestFakeEndpoint<'a> {
    type Target = netemul_network::FakeEndpointProxy;

    fn deref(&self) -> &Self::Target {
        &self.endpoint
    }
}

impl<'a> TestFakeEndpoint<'a> {
    /// Return a stream of frames.
    ///
    /// Frames will be yielded as they are read from the fake endpoint.
    pub fn frame_stream(
        &self,
    ) -> impl futures::Stream<Item = std::result::Result<(Vec<u8>, u64), fidl::Error>> + '_ {
        futures::stream::try_unfold(&self.endpoint, |ep| ep.read().map_ok(move |r| Some((r, ep))))
    }
}

impl<'a> TestEndpoint<'a> {
    /// Gets access to this device's virtual Ethernet device.
    ///
    /// Note that an error is returned if the Endpoint is not a
    /// [`netemul_network::DeviceConnection::Ethernet`].
    pub async fn get_ethernet(&self) -> Result<fidl::endpoints::ClientEnd<hw_eth::DeviceMarker>> {
        match self
            .get_device()
            .await
            .with_context(|| format!("failed to get device connection for {}", self.name))?
        {
            netemul_network::DeviceConnection::Ethernet(e) => Ok(e),
            netemul_network::DeviceConnection::NetworkDevice(_) => {
                Err(anyhow::anyhow!("Endpoint {} is not an Ethernet device", self.name))
            }
        }
    }

    /// Gets access to this device's virtual Network device.
    ///
    /// Note that an error is returned if the Endpoint is not a
    /// [`netemul_network::DeviceConnection::NetworkDevice`].
    pub async fn get_netdevice(
        &self,
    ) -> Result<(
        fidl::endpoints::ClientEnd<hw_net::DeviceMarker>,
        fidl::endpoints::ClientEnd<hw_net::MacAddressingMarker>,
    )> {
        match self
            .get_device()
            .await
            .with_context(|| format!("failed to get device connection for {}", self.name))?
        {
            netemul_network::DeviceConnection::NetworkDevice(n) => {
                Self::connect_netdevice_protocols(n)
            }
            netemul_network::DeviceConnection::Ethernet(_) => {
                Err(anyhow::anyhow!("Endpoint {} is not a Network Device", self.name))
            }
        }
    }

    /// Helper function to retrieve the protocols from a netdevice client end.
    fn connect_netdevice_protocols(
        netdevice: fidl::endpoints::ClientEnd<hw_net::DeviceInstanceMarker>,
    ) -> Result<(
        fidl::endpoints::ClientEnd<hw_net::DeviceMarker>,
        fidl::endpoints::ClientEnd<hw_net::MacAddressingMarker>,
    )> {
        let netdevice: hw_net::DeviceInstanceProxy = netdevice.into_proxy()?;
        let (device, device_server_end) =
            fidl::endpoints::create_endpoints::<hw_net::DeviceMarker>()?;
        let (mac, mac_server_end) =
            fidl::endpoints::create_endpoints::<hw_net::MacAddressingMarker>()?;
        let () = netdevice.get_device(device_server_end)?;
        let () = netdevice.get_mac_addressing(mac_server_end)?;
        Ok((device, mac))
    }

    /// Adds this endpoint to `stack`, returning the interface identifier.
    pub async fn add_to_stack(&self, stack: &net_stack::StackProxy) -> Result<u64> {
        Ok(match self.get_device().await.context("get_device failed")? {
            netemul_network::DeviceConnection::Ethernet(eth) => {
                stack.add_ethernet_interface(&self.name, eth).await.squash_result()?
            }
            netemul_network::DeviceConnection::NetworkDevice(netdevice) => {
                let (device, mac) = Self::connect_netdevice_protocols(netdevice)?;
                stack
                    .add_interface(
                        net_stack::InterfaceConfig {
                            name: None,
                            topopath: None,
                            metric: None,
                            ..net_stack::InterfaceConfig::EMPTY
                        },
                        &mut net_stack::DeviceDefinition::Ethernet(
                            net_stack::EthernetDeviceDefinition {
                                network_device: device,
                                mac: mac,
                            },
                        ),
                    )
                    .await
                    .squash_result()?
            }
        })
    }

    /// Consumes this `TestEndpoint` and tries to add it to the Netstack in
    /// `environment`, returning a [`TestInterface`] on success.
    pub async fn into_interface_in_environment(
        self,
        environment: &TestEnvironment<'a>,
    ) -> Result<TestInterface<'a>> {
        let stack = environment.connect_to_service::<net_stack::StackMarker>()?;
        let netstack = environment.connect_to_service::<netstack::NetstackMarker>()?;
        let id = self.add_to_stack(&stack).await.with_context(|| {
            format!("failed to add {} to environment {}", self.name, environment.name)
        })?;
        Ok(TestInterface { endpoint: self, id, stack, netstack })
    }
}

/// A [`TestEndpoint`] that is installed in an environment's Netstack.
#[must_use]
pub struct TestInterface<'a> {
    endpoint: TestEndpoint<'a>,
    id: u64,
    stack: net_stack::StackProxy,
    netstack: netstack::NetstackProxy,
}

impl<'a> std::ops::Deref for TestInterface<'a> {
    type Target = netemul_network::EndpointProxy;

    fn deref(&self) -> &Self::Target {
        &self.endpoint
    }
}

impl<'a> TestInterface<'a> {
    /// Gets the interface identifier.
    pub fn id(&self) -> u64 {
        self.id
    }

    /// Enable interface.
    ///
    /// Equivalent to `stack.enable_interface(test_interface.id())`.
    pub async fn enable_interface(&self) -> Result<()> {
        self.stack.enable_interface(self.id).await.squash_result().with_context(|| {
            format!("stack.enable_interface for endpoint {} failed", self.endpoint.name)
        })
    }

    /// Enable filtering on the interface.
    ///
    /// Equivalent to `stack.enable_packet_filter(test_interface.id())`.
    pub async fn enable_filter(&self) -> Result<()> {
        self.stack.enable_packet_filter(self.id).await.squash_result().with_context(|| {
            format!("stack.enable_packet_filter for endpoint {} failed", self.endpoint.name)
        })
    }

    /// Disable filtering on the interface.
    ///
    /// Equivalent to `stack.disable_packet_filter(test_interface.id())`.
    pub async fn disable_filter(&self) -> Result<()> {
        self.stack.disable_packet_filter(self.id).await.squash_result().with_context(|| {
            format!("stack.disable_packet_filter for endpoint {} failed", self.endpoint.name)
        })
    }

    /// Add interface address.
    ///
    /// Equivalent to `stack.add_interface_address(test_interface.id(), &mut addr)`.
    pub async fn add_ip_addr(&self, mut addr: net::Subnet) -> Result<()> {
        self.stack.add_interface_address(self.id, &mut addr).await.squash_result().with_context(
            || {
                format!(
                    "stack.add_interface_address({}, {:?}) for endpoint {} failed",
                    self.id, addr, self.endpoint.name
                )
            },
        )
    }

    /// Gets the interface's info.
    pub async fn get_info(&self) -> Result<net_stack::InterfaceInfo> {
        self.stack.get_interface_info(self.id).await.squash_result().with_context(|| {
            format!(
                "stack.get_interface_info({}) for endpoint {} failed",
                self.id, self.endpoint.name
            )
        })
    }

    /// Gets the interface's addresses.
    pub async fn get_addrs(&self) -> Result<Vec<net::Subnet>> {
        Ok(self.get_info().await?.properties.addresses)
    }

    async fn get_dhcp_client(&self) -> Result<net_dhcp::ClientProxy> {
        let (dhcp_client, server_end) =
            fidl::endpoints::create_proxy::<net_dhcp::ClientMarker>()
                .context("failed to create endpoints for fuchsia.net.dhcp.Client")?;

        let () = self
            .netstack
            .get_dhcp_client(
                self.id.try_into().with_context(|| {
                    format!("interface ID should fit in a u32; ID = {}", self.id)
                })?,
                server_end,
            )
            .await
            .context("failed to call netstack.get_dhcp_client")?
            .map_err(zx::Status::from_raw)
            .context("failed to get dhcp client")?;
        Ok(dhcp_client)
    }

    /// Starts DHCP on this interface.
    pub async fn start_dhcp(&self) -> Result<()> {
        let dhcp_client = self.get_dhcp_client().await?;
        let () = dhcp_client
            .start()
            .await
            .context("failed to call dhcp_client.start")?
            .map_err(zx::Status::from_raw)
            .context("failed to start dhcp client")?;

        Ok(())
    }

    /// Stops DHCP on this interface.
    pub async fn stop_dhcp(&self) -> Result<()> {
        let dhcp_client = self.get_dhcp_client().await?;
        let () = dhcp_client
            .stop()
            .await
            .context("failed to call dhcp_client.stop")?
            .map_err(zx::Status::from_raw)
            .context("failed to stop dhcp client")?;

        Ok(())
    }
}

/// Get the [`socket2::Domain`] for `addr`.
fn get_socket2_domain(addr: &std::net::SocketAddr) -> fidl_fuchsia_posix_socket::Domain {
    let domain = match addr {
        std::net::SocketAddr::V4(_) => fidl_fuchsia_posix_socket::Domain::Ipv4,
        std::net::SocketAddr::V6(_) => fidl_fuchsia_posix_socket::Domain::Ipv6,
    };

    domain
}

/// Trait describing UDP sockets that can be bound in a testing environment.
pub trait EnvironmentUdpSocket: Sized {
    /// Creates a UDP socket in `env` bound to `addr`.
    fn bind_in_env<'a>(
        env: &'a TestEnvironment<'a>,
        addr: std::net::SocketAddr,
    ) -> futures::future::LocalBoxFuture<'a, Result<Self>>;
}

impl EnvironmentUdpSocket for std::net::UdpSocket {
    fn bind_in_env<'a>(
        env: &'a TestEnvironment<'a>,
        addr: std::net::SocketAddr,
    ) -> futures::future::LocalBoxFuture<'a, Result<Self>> {
        async move {
            let sock = env
                .datagram_socket(
                    get_socket2_domain(&addr),
                    fidl_fuchsia_posix_socket::DatagramSocketProtocol::Udp,
                )
                .await
                .context("failed to create socket")?;

            let () = sock.bind(&addr.into()).context("bind failed")?;

            Result::Ok(sock.into())
        }
        .boxed_local()
    }
}

impl EnvironmentUdpSocket for fuchsia_async::net::UdpSocket {
    fn bind_in_env<'a>(
        env: &'a TestEnvironment<'a>,
        addr: std::net::SocketAddr,
    ) -> futures::future::LocalBoxFuture<'a, Result<Self>> {
        std::net::UdpSocket::bind_in_env(env, addr)
            .and_then(|udp| {
                futures::future::ready(
                    fuchsia_async::net::UdpSocket::from_socket(udp)
                        .context("failed to create fuchsia_async socket"),
                )
            })
            .boxed_local()
    }
}

/// Trait describing TCP listeners bound in a testing environment.
pub trait EnvironmentTcpListener: Sized {
    /// Creates a TCP listener in `env` bound to `addr`.
    fn listen_in_env<'a>(
        env: &'a TestEnvironment<'a>,
        addr: std::net::SocketAddr,
    ) -> futures::future::LocalBoxFuture<'a, Result<Self>> {
        Self::listen_in_env_with(env, addr, |_: &socket2::Socket| Ok(()))
    }

    /// Creates a TCP listener by creating a Socket2 socket in `env`. Closure `setup` is called with
    /// the reference of the socket before the socket is bound to `addr`.
    fn listen_in_env_with<'a>(
        env: &'a TestEnvironment<'a>,
        addr: std::net::SocketAddr,
        setup: impl FnOnce(&socket2::Socket) -> Result<()> + 'a,
    ) -> futures::future::LocalBoxFuture<'a, Result<Self>>;
}

impl EnvironmentTcpListener for std::net::TcpListener {
    fn listen_in_env_with<'a>(
        env: &'a TestEnvironment<'a>,
        addr: std::net::SocketAddr,
        setup: impl FnOnce(&socket2::Socket) -> Result<()> + 'a,
    ) -> futures::future::LocalBoxFuture<'a, Result<Self>> {
        async move {
            let sock = env
                .stream_socket(
                    get_socket2_domain(&addr),
                    fidl_fuchsia_posix_socket::StreamSocketProtocol::Tcp,
                )
                .await
                .context("failed to create server socket")?;
            let () = setup(&sock)?;
            let () = sock.bind(&addr.into()).context("failed to bind server socket")?;
            // Use 128 for the listen() backlog, same as the original implementation of TcpListener
            // in Rust std (see https://doc.rust-lang.org/src/std/sys_common/net.rs.html#386).
            let () = sock.listen(128).context("failed to listen on server socket")?;

            Result::Ok(sock.into())
        }
        .boxed_local()
    }
}

impl EnvironmentTcpListener for fuchsia_async::net::TcpListener {
    fn listen_in_env_with<'a>(
        env: &'a TestEnvironment<'a>,
        addr: std::net::SocketAddr,
        setup: impl FnOnce(&socket2::Socket) -> Result<()> + 'a,
    ) -> futures::future::LocalBoxFuture<'a, Result<Self>> {
        std::net::TcpListener::listen_in_env_with(env, addr, setup)
            .and_then(|listener| {
                futures::future::ready(
                    fuchsia_async::net::TcpListener::from_std(listener)
                        .context("failed to create fuchsia_async socket"),
                )
            })
            .boxed_local()
    }
}

/// Trait describing TCP streams in a testing environment.
pub trait EnvironmentTcpStream: Sized {
    /// Creates a TCP stream in `env` connected to `addr`.
    fn connect_in_env<'a>(
        env: &'a TestEnvironment<'a>,
        addr: std::net::SocketAddr,
    ) -> futures::future::LocalBoxFuture<'a, Result<Self>>;

    // TODO: Implement this trait for std::net::TcpStream.
}

impl EnvironmentTcpStream for fuchsia_async::net::TcpStream {
    fn connect_in_env<'a>(
        env: &'a TestEnvironment<'a>,
        addr: std::net::SocketAddr,
    ) -> futures::future::LocalBoxFuture<'a, Result<Self>> {
        async move {
            let sock = env
                .stream_socket(
                    get_socket2_domain(&addr),
                    fidl_fuchsia_posix_socket::StreamSocketProtocol::Tcp,
                )
                .await
                .context("failed to create socket")?;

            let stream = fuchsia_async::net::TcpStream::connect_from_raw(sock, addr)
                .context("failed to create client tcp stream")?
                .await
                .context("failed to connect to server")?;

            Result::Ok(stream)
        }
        .boxed_local()
    }
}
