// Copyright 2022 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 anyhow::{anyhow, Context as _};
use fidl_fuchsia_data as fdata;
use fidl_fuchsia_net_ext as fnet_ext;
use fidl_fuchsia_net_interfaces as fnet_interfaces;
use fidl_fuchsia_netemul as fnetemul;
use fidl_fuchsia_netemul_network as fnetemul_network;
use fidl_fuchsia_sys2 as fsys2;
use std::{
    collections::{hash_map, HashMap, HashSet},
    str::FromStr,
};
use tracing::{debug, info};

#[derive(Debug, PartialEq)]
pub(crate) struct Network {
    name: String,
    endpoints: Vec<Endpoint>,
}

#[derive(Debug, PartialEq)]
pub(crate) struct Endpoint {
    name: String,
    mac: Option<fnet_ext::MacAddress>,
    mtu: u16,
    up: bool,
}

impl Endpoint {
    const fn default_mtu() -> u16 {
        netemul::DEFAULT_MTU
    }

    const fn default_link_up() -> bool {
        true
    }
}

#[derive(Debug, PartialEq)]
pub(crate) struct Netstack {
    name: String,
    interfaces: Vec<Interface>,
}

#[derive(Debug, PartialEq)]
pub(crate) struct Interface {
    name: String,
    without_autogenerated_addresses: bool,
    static_ips: Vec<fnet_ext::Subnet>,
    gateway: Option<fnet_ext::IpAddress>,
    enable_ipv4_forwarding: bool,
    enable_ipv6_forwarding: bool,
}

// Represents a configuration that has been deserialized but not yet validated.
//
// To produce a valid `Config`, pass an `UnvalidatedConfig` to
// `Config::validate`.
#[derive(Debug, PartialEq)]
struct UnvalidatedConfig {
    networks: Vec<Network>,
    netstacks: Vec<Netstack>,
    eager_components: Vec<String>,
}

#[derive(Debug, PartialEq)]
pub(crate) struct Config {
    networks: Vec<Network>,
    netstacks: Vec<Netstack>,
    eager_components: Vec<String>,
}

#[derive(Debug)]
struct Dictionary(HashMap<String, Box<fdata::DictionaryValue>>);

// NB(https://fxbug.dev/42178304): `fuchsia.data/Dictionary` is produced from a
// restricted subset of JSON that appears in parts of the component manifest,
// such as the `program` section. As a result, there are some undesirable
// properties of the `Dictionary` type that arise from its JSON source. For
// example:
//  * the value of a given key is optional, given that in JSON, it could be
//    `null`;
//  * duplicate keys are allowed, and later instances of a key overwrites any
//    previous instances, as specified in the ECMA standard.
impl TryFrom<fdata::Dictionary> for Dictionary {
    type Error = anyhow::Error;

    fn try_from(dict: fdata::Dictionary) -> Result<Self, anyhow::Error> {
        let fdata::Dictionary { entries, .. } = dict;
        let entries = entries
            .context("`entries` not set in dictionary")?
            .into_iter()
            .map(|fdata::DictionaryEntry { key, value }| {
                let value = value.with_context(|| format!("value not set for key `{}`", key))?;
                Ok((key, value))
            })
            .collect::<Result<HashMap<_, _>, anyhow::Error>>()?;
        Ok(Self(entries))
    }
}

impl Dictionary {
    fn try_take_str(&mut self, key: &str) -> Option<Result<String, fdata::DictionaryValue>> {
        let Self(entries) = self;
        entries.remove(key).map(|value| match *value {
            fdata::DictionaryValue::Str(string) => Ok(string),
            other => Err(other),
        })
    }

    fn try_take_str_into<T: FromStr>(
        &mut self,
        key: &str,
    ) -> Option<Result<Result<T, <T as FromStr>::Err>, fdata::DictionaryValue>> {
        self.try_take_str(key).map(|result| result.map(|s| s.parse::<T>()))
    }

    fn try_take_str_vec(
        &mut self,
        key: &str,
    ) -> Option<Result<Vec<String>, fdata::DictionaryValue>> {
        let Self(entries) = self;
        entries.remove(key).map(|value| match *value {
            fdata::DictionaryValue::StrVec(strings) => Ok(strings),
            other => Err(other),
        })
    }

    fn try_take_obj_vec(
        &mut self,
        key: &str,
    ) -> Option<Result<Vec<fdata::Dictionary>, fdata::DictionaryValue>> {
        let Self(entries) = self;
        entries.remove(key).map(|value| {
            match *value {
                fdata::DictionaryValue::ObjVec(values) => Ok(values),
                // The component manifest parser assumes an empty list to be a list of strings,
                // so accept an empty list of strings as a valid list of objects.
                fdata::DictionaryValue::StrVec(v) if v.is_empty() => Ok(vec![]),
                other => Err(other),
            }
        })
    }

    fn into_empty(self) -> Result<(), Vec<String>> {
        let Self(entries) = self;
        if !entries.is_empty() {
            Err(entries.into_keys().collect::<Vec<_>>())
        } else {
            Ok(())
        }
    }
}

impl TryFrom<Dictionary> for Network {
    type Error = anyhow::Error;

    fn try_from(mut dict: Dictionary) -> Result<Self, Self::Error> {
        let name = dict
            .try_take_str("name")
            .context("could not find `name` in network")?
            .map_err(|e| anyhow!("`name` is not a string: {:?}", e))?;
        let endpoints = dict
            .try_take_obj_vec("endpoints")
            .with_context(|| format!("could not find `endpoints` in network `{}`", name))?
            .map_err(|e| anyhow!("`endpoints` is not a list of objects: {:?}", e))?
            .into_iter()
            .map(|dict| Dictionary::try_from(dict).and_then(Endpoint::try_from))
            .collect::<Result<Vec<_>, _>>()?;

        dict.into_empty()
            .map_err(|e| anyhow!("unrecognized fields in network `{}`: {:?}", name, e))?;

        Ok(Network { name, endpoints })
    }
}

impl TryFrom<Dictionary> for Endpoint {
    type Error = anyhow::Error;

    fn try_from(mut dict: Dictionary) -> Result<Self, Self::Error> {
        let name = dict
            .try_take_str("name")
            .context("could not find `name` in endpoint")?
            .map_err(|e| anyhow!("`name` is not a string: {:?}", e))?;
        let mac = dict
            .try_take_str_into::<fnet_ext::MacAddress>("mac")
            .transpose()
            .map_err(|e| anyhow!("`mac` is not a string: {:?}", e))?
            .transpose()
            .context("parse `mac`")?;
        let mtu = dict
            .try_take_str_into::<u16>("mtu")
            .unwrap_or_else(|| Ok(Ok(Endpoint::default_mtu())))
            .map_err(|e| anyhow!("`mtu` is not a string: {:?}", e))?
            .context("parse `mtu`")?;
        let up = dict
            .try_take_str_into::<bool>("up")
            .unwrap_or_else(|| Ok(Ok(Endpoint::default_link_up())))
            .map_err(|e| anyhow!("`up` is not a string: {:?}", e))?
            .context("parse `up`")?;

        dict.into_empty()
            .map_err(|e| anyhow!("unrecognized fields in endpoint `{}`: {:?}", name, e))?;

        Ok(Endpoint { name, mac, mtu, up })
    }
}

impl TryFrom<Dictionary> for Netstack {
    type Error = anyhow::Error;

    fn try_from(mut dict: Dictionary) -> Result<Self, Self::Error> {
        let name = dict
            .try_take_str("name")
            .context("could not find `name` in netstack")?
            .map_err(|e| anyhow!("`name` is not a string: {:?}", e))?;
        let interfaces = dict
            .try_take_obj_vec("interfaces")
            .with_context(|| format!("could not find `interfaces` in netstack `{}`", name))?
            .map_err(|e| anyhow!("`interfaces` is not a list of objects: {:?}", e))?
            .into_iter()
            .map(|dict| Dictionary::try_from(dict).and_then(Interface::try_from))
            .collect::<Result<Vec<_>, _>>()?;

        dict.into_empty()
            .map_err(|e| anyhow!("unrecognized fields in netstack `{}`: {:?}", name, e))?;

        Ok(Netstack { name, interfaces })
    }
}

impl TryFrom<Dictionary> for Interface {
    type Error = anyhow::Error;

    fn try_from(mut dict: Dictionary) -> Result<Self, Self::Error> {
        let name = dict
            .try_take_str("name")
            .context("could not find `name` in interface")?
            .map_err(|e| anyhow!("`name` is not a string: {:?}", e))?;
        let without_autogenerated_addresses = dict
            .try_take_str_into::<bool>("without_autogenerated_addresses")
            .unwrap_or_else(|| Ok(Ok(false)))
            .map_err(|e| anyhow!("`without_autogenerated_addresses` is not a string: {:?}", e))?
            .context("parse `without_autogenerated_addresses`")?;
        let static_ips = dict
            .try_take_str_vec("static_ips")
            .with_context(|| format!("could not find `static_ips` in interface `{}`", name))?
            .map_err(|e| anyhow!("`static_ips` is not a list of strings: {:?}", e))?
            .into_iter()
            .map(|s| s.parse::<fnet_ext::Subnet>())
            .collect::<Result<Vec<_>, _>>()
            .context("`static_ips` from strings")?;
        let gateway = dict
            .try_take_str_into::<fnet_ext::IpAddress>("gateway")
            .transpose()
            .map_err(|e| anyhow!("`gateway` is not a string: {:?}", e))?
            .transpose()
            .context("parse `gateway`")?;
        let enable_ipv4_forwarding = dict
            .try_take_str_into::<bool>("enable_ipv4_forwarding")
            .unwrap_or_else(|| Ok(Ok(false)))
            .map_err(|e| anyhow!("`enable_ipv4_forwarding` is not a string: {:?}", e))?
            .context("parse `enable_ipv4_forwarding`")?;
        let enable_ipv6_forwarding = dict
            .try_take_str_into::<bool>("enable_ipv6_forwarding")
            .unwrap_or_else(|| Ok(Ok(false)))
            .map_err(|e| anyhow!("`enable_ipv6_forwarding` is not a string: {:?}", e))?
            .context("parse `enable_ipv6_forwarding`")?;

        dict.into_empty()
            .map_err(|e| anyhow!("unrecognized fields in interface `{}`: {:?}", name, e))?;

        Ok(Interface {
            name,
            without_autogenerated_addresses,
            static_ips,
            gateway,
            enable_ipv4_forwarding,
            enable_ipv6_forwarding,
        })
    }
}

impl TryFrom<Dictionary> for UnvalidatedConfig {
    type Error = anyhow::Error;

    fn try_from(mut program: Dictionary) -> Result<Self, Self::Error> {
        let networks = program
            .try_take_obj_vec("networks")
            .context("could not find `networks`")?
            .map_err(|e| anyhow!("`networks` is not a list of objects: {:?}", e))?
            .into_iter()
            .map(|dict| Dictionary::try_from(dict).and_then(Network::try_from))
            .collect::<Result<Vec<_>, _>>()?;
        let netstacks = program
            .try_take_obj_vec("netstacks")
            .context("could not find `netstacks`")?
            .map_err(|e| anyhow!("`netstacks` is not a list of objects: {:?}", e))?
            .into_iter()
            .map(|dict| Dictionary::try_from(dict).and_then(Netstack::try_from))
            .collect::<Result<Vec<_>, _>>()?;
        let eager_components = program
            .try_take_str_vec("start")
            .transpose()
            .map_err(|e| anyhow!("`start` is not a list of strings: {:?}", e))?
            .unwrap_or_default();

        program.into_empty().map_err(|e| anyhow!("unrecognized fields in `program`: {:?}", e))?;

        Ok(Self { networks, netstacks, eager_components })
    }
}

#[derive(thiserror::Error, Debug, PartialEq)]
pub(crate) enum Error {
    #[error("duplicate network `{0}`, network names must be unique")]
    DuplicateNetwork(String),
    #[error("duplicate netstack `{0}`, netstack names must be unique")]
    DuplicateNetstack(String),
    #[error("duplicate endpoint `{0}`, endpoint names must be unique")]
    DuplicateEndpoint(String),
    #[error("endpoint `{0}` assigned to a netstack multiple times")]
    EndpointAssignedMultipleTimes(String),
    #[error(
        "endpoint name '{0}' exceeds maximum interface name length of {}",
        fnet_interfaces::INTERFACE_NAME_LENGTH
    )]
    EndpointNameExceedsMaximumLength(String),
    #[error("unknown endpoint `{0}`, must be declared on a network")]
    UnknownEndpoint(String),
    #[error("duplicate eager component `{0}`, component names must be unique")]
    DuplicateEagerComponent(String),
}

impl UnvalidatedConfig {
    fn validate(self) -> Result<Config, Error> {
        let Self { networks, netstacks, eager_components } = &self;

        let mut network_names = HashSet::new();
        let mut installed_endpoints = HashMap::new();
        for Network { name, endpoints } in networks {
            if !network_names.insert(name) {
                return Err(Error::DuplicateNetwork(name.to_string()));
            }
            for Endpoint { name, .. } in endpoints {
                if let Some(_) = installed_endpoints.insert(name, false) {
                    return Err(Error::DuplicateEndpoint(name.to_string()));
                }
                if name.len() > fnet_interfaces::INTERFACE_NAME_LENGTH.into() {
                    return Err(Error::EndpointNameExceedsMaximumLength(name.to_string()));
                }
            }
        }

        let mut netstack_names = HashSet::new();
        for Netstack { name, interfaces } in netstacks {
            if !netstack_names.insert(name) {
                return Err(Error::DuplicateNetstack(name.to_string()));
            }
            for Interface { name, .. } in interfaces {
                match installed_endpoints.entry(&name) {
                    hash_map::Entry::Occupied(mut entry) => {
                        if *entry.get() {
                            return Err(Error::EndpointAssignedMultipleTimes(name.to_string()));
                        } else {
                            *entry.get_mut() = true;
                        }
                    }
                    hash_map::Entry::Vacant(_) => {
                        return Err(Error::UnknownEndpoint(name.to_string()));
                    }
                }
            }
        }

        let mut eager_component_names = HashSet::new();
        for name in eager_components {
            if !eager_component_names.insert(name) {
                return Err(Error::DuplicateEagerComponent(name.to_string()));
            }
        }

        let Self { networks, netstacks, eager_components } = self;
        Ok(Config { networks, netstacks, eager_components })
    }
}

/// A handle to the virtual network environment created for the test.
///
/// This encodes the lifetime of the network environment, as the netemul sandbox
/// and any networks or endpoints it contains are garbage-collected when the
/// client end of their control channel is dropped.
pub(crate) struct NetworkEnvironment {
    // We only start a test sandbox if the requested configuration requires it.
    _sandbox: Option<netemul::TestSandbox>,
    _networks: HashMap<String, fnetemul_network::NetworkProxy>,
    _endpoints: HashMap<String, fnetemul_network::EndpointProxy>,
}

impl Config {
    /// Loads the virtual network configuration that the test should be run in.
    pub(crate) fn load_from_program(program: fdata::Dictionary) -> Result<Self, anyhow::Error> {
        let program = Dictionary::try_from(program).context("program into dictionary")?;
        UnvalidatedConfig::try_from(program)
            .context("parsing config from `program`")?
            .validate()
            .context("validating config")
    }

    /// Applies the virtual network configuration.
    ///
    /// A netemul sandbox is used to create virtual networks and endpoints, and the
    /// netstacks to be configured are connected to with `connect_to_netstack`.
    ///
    /// Returns a handle to the network environment.
    pub(crate) async fn apply<F>(
        self,
        mut connect_to_netstack: F,
        lifecycle_controller: fsys2::LifecycleControllerProxy,
    ) -> Result<NetworkEnvironment, anyhow::Error>
    where
        F: FnMut(String) -> Result<fnetemul::ConfigurableNetstackProxy, anyhow::Error>,
    {
        info!("configuring environment for test: {:#?}", self);
        let Self { networks, netstacks, eager_components } = self;

        // Create the networks and endpoints in a netemul sandbox.
        let mut maybe_sandbox = None;
        let mut network_handles = HashMap::new();
        let mut endpoint_handles = HashMap::new();
        for Network { name, endpoints } in networks {
            let sandbox = if let Some(sandbox) = maybe_sandbox.as_ref() {
                sandbox
            } else {
                maybe_sandbox.insert(netemul::TestSandbox::new().context("create test sandbox")?)
            };
            let network = sandbox
                .create_network(name.clone())
                .await
                .with_context(|| format!("create network `{}`", name))?;
            for Endpoint { name, mac, mtu, up } in endpoints {
                let endpoint = network
                    .create_endpoint_with(
                        name.clone(),
                        fnetemul_network::EndpointConfig {
                            mac: mac.map(Into::into).map(Box::new),
                            mtu,
                            port_class: fidl_fuchsia_hardware_network::PortClass::Virtual,
                        },
                    )
                    .await
                    .with_context(|| format!("create endpoint `{}`", name))?;
                if up {
                    endpoint.set_link_up(true).await.context("set link up")?;
                }
                assert!(endpoint_handles.insert(name, endpoint.into_proxy()).is_none());
            }
            assert!(network_handles.insert(name, network.into_proxy()).is_none());
        }

        // Configure the netstacks.
        for Netstack { name, interfaces } in netstacks {
            debug!("configuring netstack `{}`", name);
            let netstack = connect_to_netstack(name).context("connect to configurable netstack")?;

            for Interface {
                name,
                without_autogenerated_addresses,
                static_ips,
                gateway,
                enable_ipv4_forwarding,
                enable_ipv6_forwarding,
            } in interfaces
            {
                debug!("configuring interface `{}` with static IPs {:?}", name, static_ips);

                let (port, server_end) = fidl::endpoints::create_endpoints();
                endpoint_handles
                    .get(&name)
                    .with_context(|| format!("could not find endpoint `{}`", name))?
                    .get_port(server_end)
                    .with_context(|| format!("retrieve device from test endpoint `{}`", name))?;

                let options = fnetemul::InterfaceOptions {
                    name: Some(name.to_string()),
                    device: Some(port),
                    without_autogenerated_addresses: Some(without_autogenerated_addresses),
                    static_ips: Some(static_ips.into_iter().map(Into::into).collect()),
                    gateway: gateway.map(Into::into),
                    enable_ipv4_forwarding: Some(enable_ipv4_forwarding),
                    enable_ipv6_forwarding: Some(enable_ipv6_forwarding),
                    ..Default::default()
                };
                netstack
                    .configure_interface(options)
                    .await
                    .context("call configure interface")?
                    .map_err(|e| anyhow!("error configuring netstack: {:?}", e))?;
            }
        }

        // Start all the eager components now that test setup is complete.
        for component in eager_components {
            let (_, binder_server) =
                fidl::endpoints::create_endpoints::<fidl_fuchsia_component::BinderMarker>();
            lifecycle_controller
                .start_instance(&format!("./{}", component), binder_server)
                .await
                .context("call start")?
                .map_err(|e| anyhow!("failed to start component '{}': {:?}", component, e))?
        }

        Ok(NetworkEnvironment {
            _sandbox: maybe_sandbox,
            _networks: network_handles,
            _endpoints: endpoint_handles,
        })
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use assert_matches::assert_matches;
    use futures::{channel::mpsc, StreamExt as _, TryStreamExt as _};
    use net_declare::{fidl_ip, fidl_mac, fidl_subnet};
    use test_case::test_case;

    const LOCAL_NETSTACK: &str = "local";
    const REMOTE_NETSTACK: &str = "remote";

    fn example_config() -> Config {
        Config {
            netstacks: vec![
                Netstack {
                    name: LOCAL_NETSTACK.to_string(),
                    interfaces: vec![
                        Interface {
                            name: "local-ep1".to_string(),
                            without_autogenerated_addresses: true,
                            static_ips: vec![fidl_subnet!("192.168.0.2/24").into()],
                            gateway: Some(fidl_ip!("192.168.1.1").into()),
                            enable_ipv4_forwarding: true,
                            enable_ipv6_forwarding: true,
                        },
                        Interface {
                            name: "local-ep2".to_string(),
                            without_autogenerated_addresses: false,
                            static_ips: vec![fidl_subnet!("192.168.0.3/24").into()],
                            gateway: None,
                            enable_ipv4_forwarding: false,
                            enable_ipv6_forwarding: false,
                        },
                    ],
                },
                Netstack {
                    name: REMOTE_NETSTACK.to_string(),
                    interfaces: vec![Interface {
                        name: "remote-ep".to_string(),
                        without_autogenerated_addresses: false,
                        static_ips: vec![fidl_subnet!("192.168.0.1/24").into()],
                        gateway: None,
                        enable_ipv4_forwarding: false,
                        enable_ipv6_forwarding: false,
                    }],
                },
            ],
            networks: vec![Network {
                name: "net".to_string(),
                endpoints: vec![
                    Endpoint {
                        name: "local-ep1".to_string(),
                        mac: Some(fidl_mac!("aa:bb:cc:dd:ee:ff").into()),
                        mtu: 999,
                        up: false,
                    },
                    Endpoint {
                        name: "local-ep2".to_string(),
                        mac: None,
                        mtu: Endpoint::default_mtu(),
                        up: Endpoint::default_link_up(),
                    },
                    Endpoint {
                        name: "remote-ep".to_string(),
                        mac: None,
                        mtu: Endpoint::default_mtu(),
                        up: Endpoint::default_link_up(),
                    },
                ],
            }],
            eager_components: vec!["foo".to_string(), "bar".to_string()],
        }
    }

    fn program_from_str(program: &str) -> fdata::Dictionary {
        let object = serde_json::from_str(program).expect("deserialize JSON object");
        let cm_rust::ComponentDecl { program, .. } =
            cm_rust_testing::new_decl_from_json(object).expect("deserialize component decl");
        let cm_rust::ProgramDecl { info, runner: _ } =
            program.expect("`program` not set in component decl");
        info
    }

    #[test]
    fn valid_config() {
        let file = r#"
{
    "program": {
        "runner": "elf",
        "netstacks": [
            {
                "name": "local",
                "interfaces": [
                    {
                        "name": "local-ep1",
                        "without_autogenerated_addresses": "true",
                        "static_ips": [ "192.168.0.2/24" ],
                        "gateway": "192.168.1.1",
                        "enable_ipv4_forwarding": "true",
                        "enable_ipv6_forwarding": "true"
                    },
                    {
                        "name": "local-ep2",
                        "static_ips": [ "192.168.0.3/24" ]
                    }
                ]
            },
            {
                "name": "remote",
                "interfaces": [
                    {
                        "name": "remote-ep",
                        "static_ips": [ "192.168.0.1/24" ]
                    }
                ]
            }
        ],
        "networks": [
            {
                "name": "net",
                "endpoints": [
                    {
                        "name": "local-ep1",
                        "mac": "aa:bb:cc:dd:ee:ff",
                        "mtu": "999",
                        "up": "false"
                    },
                    {
                        "name": "local-ep2"
                    },
                    {
                        "name": "remote-ep"
                    }
                ]
            }
        ],
        "start": ["foo", "bar"]
    }
}
"#;

        let program = program_from_str(file);
        let config = Config::load_from_program(program).expect("parse network config");
        assert_eq!(config, example_config());
    }

    #[test_case(r#"{ "program": { "runner": "elf", "netstacks": [] } }"#; "missing required field `networks`")]
    #[test_case(
        r#"{
            "program": {
                "runner": "elf",
                "netstacks": [],
                "networks": [],
                "endpoints": []
            }
        }"#;
        "unknown field `endpoints`"
    )]
    #[test_case(
        r#"{
            "program": {
                "runner": "elf",
                "netstacks": [],
                "networks": [
                    {
                        "name": "net",
                        "endpoints": [
                            {
                                "name": "ep",
                                "mtu": "65536"
                            }
                        ]
                    }
                ]
            }
        }"#;
        "invalid endpoint MTU (larger than `u16::MAX`)"
    )]
    #[test_case(
        r#"{
            "program": {
                "runner": "elf",
                "netstacks": [
                    {
                        "name": "ns",
                        "interfaces": [
                            {
                                "name": "if",
                                "static_ips": ["not an IP address"]
                            }
                        ]
                    }
                ],
                "networks": []
            }
        }"#;
        "invalid static interface address"
    )]
    fn invalid_parse(s: &str) {
        let program = program_from_str(s);
        let program = Dictionary::try_from(program).expect("program into dictionary");
        assert_matches!(UnvalidatedConfig::try_from(program), Err(_));
    }

    #[test_case(
        UnvalidatedConfig {
            netstacks: vec![
                Netstack {
                    name: "netstack".to_string(),
                    interfaces: vec![
                        Interface {
                            name: "ep".to_string(),
                            without_autogenerated_addresses: false,
                            static_ips: vec![],
                            gateway: None,
                            enable_ipv4_forwarding: false,
                            enable_ipv6_forwarding: false,
                        },
                    ],
                },
            ],
            networks: vec![],
            eager_components: vec![],
        },
        Error::UnknownEndpoint("ep".to_string());
        "netstack interfaces must be declared as endpoints on a network"
    )]
    #[test_case(
        UnvalidatedConfig {
            netstacks: vec![
                Netstack {
                    name: "netstack".to_string(),
                    interfaces: vec![],
                },
                Netstack {
                    name: "netstack".to_string(),
                    interfaces: vec![],
                },
            ],
            networks: vec![],
            eager_components: vec![],
        },
        Error::DuplicateNetstack("netstack".to_string());
        "netstack names must be unique"
    )]
    #[test_case(
        UnvalidatedConfig {
            netstacks: vec![],
            networks: vec![
                Network {
                    name: "net".to_string(),
                    endpoints: vec![],
                },
                Network {
                    name: "net".to_string(),
                    endpoints: vec![],
                },
            ],
            eager_components: vec![],
        },
        Error::DuplicateNetwork("net".to_string());
        "network names must be unique"
    )]
    #[test_case(
        UnvalidatedConfig {
            netstacks: vec![],
            networks: vec![
                Network {
                    name: "net".to_string(),
                    endpoints: vec![
                        Endpoint {
                            name: "ep".to_string(),
                            mac: None,
                            mtu: Endpoint::default_mtu(),
                            up: Endpoint::default_link_up(),
                        },
                        Endpoint {
                            name: "ep".to_string(),
                            mac: None,
                            mtu: Endpoint::default_mtu(),
                            up: Endpoint::default_link_up(),
                        },
                    ],
                },
            ],
            eager_components: vec![],
        },
        Error::DuplicateEndpoint("ep".to_string());
        "endpoint names must be unique"
    )]
    #[test_case(
        UnvalidatedConfig {
            netstacks: vec![],
            networks: vec![
                Network {
                    name: "net".to_string(),
                    endpoints: vec![
                        Endpoint {
                            name: "overly-long-ep-name".to_string(),
                            mac: None,
                            mtu: Endpoint::default_mtu(),
                            up: Endpoint::default_link_up(),
                        },
                    ],
                },
            ],
            eager_components: vec![],
        },
        Error::EndpointNameExceedsMaximumLength("overly-long-ep-name".to_string());
        "endpoint name must be <= maximum interface name length"
    )]
    #[test_case(
        UnvalidatedConfig {
            netstacks: vec![
                Netstack {
                    name: "ns1".to_string(),
                    interfaces: vec![
                        Interface {
                            name: "ep".to_string(),
                            without_autogenerated_addresses: false,
                            static_ips: vec![],
                            gateway: None,
                            enable_ipv4_forwarding: false,
                            enable_ipv6_forwarding: false,
                        },
                    ],
                },
                Netstack {
                    name: "ns2".to_string(),
                    interfaces: vec![
                        Interface {
                            name: "ep".to_string(),
                            without_autogenerated_addresses: false,
                            static_ips: vec![],
                            gateway: None,
                            enable_ipv4_forwarding: false,
                            enable_ipv6_forwarding: false,
                        },
                    ],
                },
            ],
            networks: vec![
                Network {
                    name: "net".to_string(),
                    endpoints: vec![
                        Endpoint {
                            name: "ep".to_string(),
                            mac: None,
                            mtu: Endpoint::default_mtu(),
                            up: Endpoint::default_link_up(),
                        },
                    ],
                },
            ],
            eager_components: vec![],
        },
        Error::EndpointAssignedMultipleTimes("ep".to_string());
        "endpoints may only be assigned once to a single netstack"
    )]
    #[test_case(
        UnvalidatedConfig {
            netstacks: vec![],
            networks: vec![],
            eager_components: vec!["server".to_string(), "server".to_string()],
        },
        Error::DuplicateEagerComponent("server".to_string());
        "eager components must be unique"
    )]
    fn invalid_config(config: UnvalidatedConfig, error: Error) {
        assert_eq!(config.validate(), Err(error));
    }

    async fn expect_incoming_requests(
        rx: &mut mpsc::UnboundedReceiver<(String, fnetemul::ConfigurableNetstackRequestStream)>,
        expected_netstack: &str,
        expected_configs: Vec<Interface>,
    ) {
        let (netstack, mut stream) =
            rx.next().await.expect("no connection requests for mock netstack");
        assert_eq!(
            netstack, expected_netstack,
            "expected request for netstack '{}', got '{}'",
            expected_netstack, netstack
        );
        for expected_config in expected_configs {
            let fnetemul::ConfigurableNetstackRequest::ConfigureInterface { payload, responder } =
                stream
                    .next()
                    .await
                    .expect("expected request not received by mock configurable netstack")
                    .expect("FIDL error on request");
            let fnetemul::InterfaceOptions {
                name,
                without_autogenerated_addresses,
                static_ips,
                gateway,
                enable_ipv4_forwarding,
                enable_ipv6_forwarding,
                device: _,
                ..
            } = payload;
            assert_eq!(
                Interface {
                    name: name.expect("missing interface name"),
                    without_autogenerated_addresses: without_autogenerated_addresses
                        .unwrap_or_default(),
                    static_ips: static_ips
                        .unwrap_or_default()
                        .into_iter()
                        .map(Into::into)
                        .collect(),
                    gateway: gateway.map(Into::into),
                    enable_ipv4_forwarding: enable_ipv4_forwarding.unwrap_or_default(),
                    enable_ipv6_forwarding: enable_ipv6_forwarding.unwrap_or_default(),
                },
                expected_config
            );
            responder.send(Ok(())).expect("send response");
        }
        let remaining = stream
            .map_ok(
                |fnetemul::ConfigurableNetstackRequest::ConfigureInterface {
                     payload,
                     responder: _,
                 }| payload,
            )
            .try_collect::<Vec<_>>()
            .await
            .expect("collect remaining requests");
        assert_eq!(remaining, vec![]);
    }

    #[fuchsia::test]
    async fn configurable_netstack() {
        let (tx, mut rx) = mpsc::unbounded();
        let (controller, server_end) =
            fidl::endpoints::create_proxy::<fsys2::LifecycleControllerMarker>()
                .expect("create proxy");
        drop(server_end);
        let configure_environment = async {
            Config {
                // Don't test eager components here.
                eager_components: vec![],
                ..example_config()
            }
            .apply(
                |name| {
                    let (proxy, server_end) =
                        fidl::endpoints::create_proxy::<fnetemul::ConfigurableNetstackMarker>()
                            .context("create proxy")?;
                    let stream =
                        server_end.into_stream().context("server end into request stream")?;
                    tx.unbounded_send((name, stream))
                        .expect("request stream receiver should not be closed");
                    Ok(proxy)
                },
                controller,
            )
            .await
            .expect("configure network environment for test")
        };
        let mock_netstack = async {
            // Expect netstacks to be configured in the order in which they're declared: the
            // "local" netstack first and "remote" second. The same order applies to the
            // interfaces that are installed in the netstacks.
            expect_incoming_requests(
                &mut rx,
                LOCAL_NETSTACK,
                vec![
                    Interface {
                        name: "local-ep1".to_string(),
                        without_autogenerated_addresses: true,
                        static_ips: vec![fidl_subnet!("192.168.0.2/24").into()],
                        gateway: Some(fidl_ip!("192.168.1.1").into()),
                        enable_ipv4_forwarding: true,
                        enable_ipv6_forwarding: true,
                    },
                    Interface {
                        name: "local-ep2".to_string(),
                        without_autogenerated_addresses: false,
                        static_ips: vec![fidl_subnet!("192.168.0.3/24").into()],
                        gateway: None,
                        enable_ipv4_forwarding: false,
                        enable_ipv6_forwarding: false,
                    },
                ],
            )
            .await;
            expect_incoming_requests(
                &mut rx,
                REMOTE_NETSTACK,
                vec![Interface {
                    name: "remote-ep".to_string(),
                    without_autogenerated_addresses: false,
                    static_ips: vec![fidl_subnet!("192.168.0.1/24").into()],
                    gateway: None,
                    enable_ipv4_forwarding: false,
                    enable_ipv6_forwarding: false,
                }],
            )
            .await;
        };
        let (NetworkEnvironment { _sandbox: sandbox, _networks, _endpoints }, ()) =
            futures::future::join(configure_environment, mock_netstack).await;
        let sandbox = sandbox.expect("sandbox was not configured");

        let network_manager = sandbox.get_network_manager().expect("get network manager");
        let networks = network_manager.list_networks().await.expect("list virtual networks");
        assert_eq!(networks, vec!["net".to_string()]);
        let endpoint_manager = sandbox.get_endpoint_manager().expect("get endpoint manager");
        let mut endpoints =
            endpoint_manager.list_endpoints().await.expect("list virtual endpoints");
        endpoints.sort();
        assert_eq!(
            endpoints,
            vec!["local-ep1".to_string(), "local-ep2".to_string(), "remote-ep".to_string()],
        );
    }

    #[fuchsia::test]
    async fn eager_components() {
        let (controller, controller_requests) =
            fidl::endpoints::create_proxy_and_stream::<fsys2::LifecycleControllerMarker>()
                .expect("create proxy and stream");
        let configure_environment = async {
            let config = Config {
                networks: vec![],
                netstacks: vec![],
                eager_components: vec!["foo".to_string(), "bar".to_string(), "baz".to_string()],
            };
            config
                .apply(
                    |_name| {
                        let (proxy, server_end) =
                            fidl::endpoints::create_proxy::<fnetemul::ConfigurableNetstackMarker>()
                                .context("create proxy")?;
                        drop(server_end);
                        Ok(proxy)
                    },
                    controller,
                )
                .await
                .expect("configure network environment for test")
        };
        let mock_lifecycle_controller = controller_requests
            .map(|request| {
                let (moniker, _, responder) = request
                    .expect("get request")
                    .into_start_instance()
                    .expect("unexpected lifecycle controller request");
                responder.send(Ok(())).expect("send response");
                moniker
            })
            .collect::<Vec<String>>();
        let (_network_environment, started_components) =
            futures::future::join(configure_environment, mock_lifecycle_controller).await;

        assert_eq!(started_components, vec!["./foo", "./bar", "./baz"]);
    }
}
