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

//! Provides utilities for test environments.

use fidl_fuchsia_net_filter;
use fidl_fuchsia_net_stack as net_stack;
use fidl_fuchsia_netemul_environment as netemul_environment;

use anyhow::Context as _;
use async_trait::async_trait;

use crate::Result;

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

/// The Netstack version. Used to specify which Netstack version to use in a
/// Netstack-served [`KnownServices`].
#[derive(Copy, Clone, Eq, PartialEq, Debug)]
#[allow(missing_docs)]
pub enum NetstackVersion {
    Netstack2,
    Netstack3,
}

impl NetstackVersion {
    /// Gets the Fuchsia URL for this Netstack component.
    pub fn get_url(&self) -> &'static str {
        match self {
            NetstackVersion::Netstack2 => {
                "fuchsia-pkg://fuchsia.com/netstack-integration-tests#meta/netstack-debug.cmx"
            }
            NetstackVersion::Netstack3 => {
                "fuchsia-pkg://fuchsia.com/netstack-integration-tests#meta/netstack3.cmx"
            }
        }
    }

    /// Gets the Netstack name.
    pub fn get_name(&self) -> &'static str {
        match self {
            NetstackVersion::Netstack2 => "ns2",
            NetstackVersion::Netstack3 => "ns3",
        }
    }
}

/// Known services used in tests.
#[derive(Copy, Clone, Eq, PartialEq, Debug)]
#[allow(missing_docs)]
pub enum KnownServices {
    Stack(NetstackVersion),
    Netstack(NetstackVersion),
    SocketProvider(NetstackVersion),
    Filter(NetstackVersion),
    RoutesState(NetstackVersion),
    InterfaceState(NetstackVersion),
    Log(NetstackVersion),
    NeighborView(NetstackVersion),
    NeighborController(NetstackVersion),
    MockCobalt,
    SecureStash,
    DhcpServer,
    Dhcpv6Client,
    LookupAdmin,
}

impl KnownServices {
    /// Gets the service name and its Fuchsia package URL.
    pub fn get_name_url(&self) -> (&'static str, &'static str) {
        match self {
            KnownServices::Stack(v) => (<net_stack::StackMarker as fidl::endpoints::DiscoverableService>::SERVICE_NAME,
                                        v.get_url()),
            KnownServices::MockCobalt => (<fidl_fuchsia_cobalt::LoggerFactoryMarker as fidl::endpoints::DiscoverableService>::SERVICE_NAME,
                                          "fuchsia-pkg://fuchsia.com/netstack-integration-tests#meta/mock_cobalt.cmx"),
            KnownServices::Netstack(v) => (<fidl_fuchsia_netstack::NetstackMarker as fidl::endpoints::DiscoverableService>::SERVICE_NAME,
                                           v.get_url()),
            KnownServices::SocketProvider(v) => (<fidl_fuchsia_posix_socket::ProviderMarker as fidl::endpoints::DiscoverableService>::SERVICE_NAME,
                                                 v.get_url()),
            KnownServices::Filter(v) => (<fidl_fuchsia_net_filter::FilterMarker as fidl::endpoints::DiscoverableService>::SERVICE_NAME,
                                         v.get_url()),
            KnownServices::RoutesState(v) => (<fidl_fuchsia_net_routes::StateMarker as fidl::endpoints::DiscoverableService>::SERVICE_NAME,
                                              v.get_url()),
            KnownServices::InterfaceState(v) => (<fidl_fuchsia_net_interfaces::StateMarker as fidl::endpoints::DiscoverableService>::SERVICE_NAME,
                                                 v.get_url()),
            KnownServices::Log(v) => (<fidl_fuchsia_net_stack::LogMarker as fidl::endpoints::DiscoverableService>::SERVICE_NAME,
                                      v.get_url()),
            KnownServices::NeighborView(v) => (<fidl_fuchsia_net_neighbor::ViewMarker as fidl::endpoints::DiscoverableService>::SERVICE_NAME,
                                               v.get_url()),
            KnownServices::NeighborController(v) => (<fidl_fuchsia_net_neighbor::ControllerMarker as fidl::endpoints::DiscoverableService>::SERVICE_NAME,
                                                     v.get_url()),
            KnownServices::SecureStash => (<fidl_fuchsia_stash::SecureStoreMarker as fidl::endpoints::DiscoverableService>::SERVICE_NAME,
                                           "fuchsia-pkg://fuchsia.com/netstack-integration-tests#meta/stash_secure.cmx"),
            KnownServices::DhcpServer => (<fidl_fuchsia_net_dhcp::Server_Marker as fidl::endpoints::DiscoverableService>::SERVICE_NAME,
                                          "fuchsia-pkg://fuchsia.com/netstack-integration-tests#meta/dhcpd.cmx"),
            KnownServices::Dhcpv6Client => (<fidl_fuchsia_net_dhcpv6::ClientProviderMarker as fidl::endpoints::DiscoverableService>::SERVICE_NAME,
                                            "fuchsia-pkg://fuchsia.com/netstack-integration-tests#meta/dhcpv6-client.cmx"),
            KnownServices::LookupAdmin => (<fidl_fuchsia_net_name::LookupAdminMarker as fidl::endpoints::DiscoverableService>::SERVICE_NAME,
                                           "fuchsia-pkg://fuchsia.com/netstack-integration-tests#meta/dns-resolver.cmx")
        }
    }

    /// Gets the service name.
    pub fn get_name(&self) -> &'static str {
        self.get_name_url().0
    }

    /// Gets the service URL.
    pub fn get_url(&self) -> &'static str {
        self.get_name_url().1
    }

    /// Transforms into a [`netemul_environment::LaunchService`] with no
    /// arguments.
    pub fn into_launch_service(self) -> netemul_environment::LaunchService {
        let (name, url) = self.get_name_url();
        netemul_environment::LaunchService {
            name: name.to_string(),
            url: url.to_string(),
            arguments: vec![],
        }
    }
}

impl<'a> From<&'a KnownServices> for netemul_environment::LaunchService {
    fn from(s: &'a KnownServices) -> Self {
        s.into_launch_service()
    }
}

/// Abstraction for a Fuchsia component which offers network stack services.
pub trait Netstack: Copy + Clone {
    /// The Netstack version.
    const VERSION: NetstackVersion;
}

/// Uninstantiable type that represents Netstack2's implementation of a
/// network stack.
#[derive(Copy, Clone)]
pub enum Netstack2 {}

impl Netstack for Netstack2 {
    const VERSION: NetstackVersion = NetstackVersion::Netstack2;
}

/// Uninstantiable type that represents Netstack3's implementation of a
/// network stack.
#[derive(Copy, Clone)]
pub enum Netstack3 {}

impl Netstack for Netstack3 {
    const VERSION: NetstackVersion = NetstackVersion::Netstack3;
}

/// Abstraction for a Fuchsia component which offers network configuration services.
pub trait Manager: Copy + Clone {
    /// The Fuchsia package URL to the component.
    const PKG_URL: &'static str;

    /// Default arguments that should be passed to the component when run under a test
    /// environment.
    const TESTING_ARGS: &'static [&'static str];

    /// Returns `TESTING_ARGS` as a type that [`fuchsia_component::client::launch`]
    /// accepts.
    fn testing_args() -> Option<Vec<String>> {
        Some(Self::TESTING_ARGS.iter().cloned().map(String::from).collect())
    }
}

/// Uninstantiable type that represents NetCfg's implementation of a network manager.
#[derive(Copy, Clone)]
pub enum NetCfg {}

impl Manager for NetCfg {
    // Note, netcfg.cmx must never be used in a Netemul environment as it breaks
    // hermeticity.
    const PKG_URL: &'static str =
        "fuchsia-pkg://fuchsia.com/netstack-integration-tests#meta/netcfg-netemul.cmx";
    // Specify an empty config file for NetCfg when it is run in netemul.
    const TESTING_ARGS: &'static [&'static str] = &["--config-data", "netcfg/empty.json"];
}

/// Uninstantiable type that represents NetworkManager's implementation of a network manager.
#[derive(Copy, Clone)]
pub enum NetworkManager {}

impl Manager for NetworkManager {
    // Note, network-manager.cmx must never be used in a Netemul environment as it breaks
    // hermeticity.
    const PKG_URL: &'static str =
        "fuchsia-pkg://fuchsia.com/netstack-integration-tests#meta/network-manager-netemul.cmx";
    const TESTING_ARGS: &'static [&'static str] = &[];
}

/// Extensions to `netemul::TestSandbox`.
#[async_trait]
pub trait TestSandboxExt {
    /// Creates an environment with Netstack services.
    fn create_netstack_environment<N, S>(&self, name: S) -> Result<netemul::TestEnvironment<'_>>
    where
        N: Netstack,
        S: Into<String>;

    /// Creates an environment with the base Netstack services plus additional
    /// ones in `services`.
    fn create_netstack_environment_with<N, S, I>(
        &self,
        name: S,
        services: I,
    ) -> Result<netemul::TestEnvironment<'_>>
    where
        S: Into<String>,
        N: Netstack,
        I: IntoIterator,
        I::Item: Into<netemul_environment::LaunchService>;

    /// Helper function to create a new Netstack environment and connect to a
    /// netstack service on it.
    fn new_netstack<N, S, T>(&self, name: T) -> Result<(netemul::TestEnvironment<'_>, S::Proxy)>
    where
        N: Netstack,
        S: fidl::endpoints::ServiceMarker + fidl::endpoints::DiscoverableService,
        T: Into<String>;

    /// Helper function to create a new Netstack environment and a new
    /// unattached endpoint.
    async fn new_netstack_and_device<N, E, S, T>(
        &self,
        name: T,
    ) -> Result<(netemul::TestEnvironment<'_>, S::Proxy, netemul::TestEndpoint<'_>)>
    where
        N: Netstack,
        E: netemul::Endpoint,
        S: fidl::endpoints::ServiceMarker + fidl::endpoints::DiscoverableService,
        T: Into<String> + Copy + Send;
}

#[async_trait]
impl TestSandboxExt for netemul::TestSandbox {
    /// Creates an environment with Netstack services.
    fn create_netstack_environment<N, S>(&self, name: S) -> Result<netemul::TestEnvironment<'_>>
    where
        N: Netstack,
        S: Into<String>,
    {
        self.create_netstack_environment_with::<N, _, _>(name, NO_SERVICES)
    }

    /// Creates an environment with the base Netstack services plus additional
    /// ones in `services`.
    fn create_netstack_environment_with<N, S, I>(
        &self,
        name: S,
        services: I,
    ) -> Result<netemul::TestEnvironment<'_>>
    where
        S: Into<String>,
        N: Netstack,
        I: IntoIterator,
        I::Item: Into<netemul_environment::LaunchService>,
    {
        self.create_environment(
            name,
            [
                KnownServices::RoutesState(N::VERSION),
                KnownServices::Filter(N::VERSION),
                KnownServices::Stack(N::VERSION),
                KnownServices::Netstack(N::VERSION),
                KnownServices::SocketProvider(N::VERSION),
                KnownServices::InterfaceState(N::VERSION),
                KnownServices::Log(N::VERSION),
                KnownServices::NeighborView(N::VERSION),
                KnownServices::NeighborController(N::VERSION),
                KnownServices::MockCobalt,
            ]
            .iter()
            .map(netemul_environment::LaunchService::from)
            .chain(services.into_iter().map(Into::into)),
        )
    }

    /// Helper function to create a new Netstack environment and connect to a
    /// netstack service on it.
    fn new_netstack<N, S, T>(&self, name: T) -> Result<(netemul::TestEnvironment<'_>, S::Proxy)>
    where
        N: Netstack,
        S: fidl::endpoints::ServiceMarker + fidl::endpoints::DiscoverableService,
        T: Into<String>,
    {
        let env = self
            .create_netstack_environment::<N, _>(name)
            .context("failed to create test environment")?;
        let netstack_proxy =
            env.connect_to_service::<S>().context("failed to connect to netstack")?;
        Ok((env, netstack_proxy))
    }

    /// Helper function to create a new Netstack environment and a new
    /// unattached endpoint.
    async fn new_netstack_and_device<N, E, S, T>(
        &self,
        name: T,
    ) -> Result<(netemul::TestEnvironment<'_>, S::Proxy, netemul::TestEndpoint<'_>)>
    where
        N: Netstack,
        E: netemul::Endpoint,
        S: fidl::endpoints::ServiceMarker + fidl::endpoints::DiscoverableService,
        T: Into<String> + Copy + Send,
    {
        let (env, stack) = self.new_netstack::<N, S, _>(name)?;
        let endpoint =
            self.create_endpoint::<E, _>(name).await.context("failed to create endpoint")?;
        Ok((env, stack, endpoint))
    }
}
