// Copyright 2019 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 {
    fidl::encoding::OutOfLine,
    fidl_fuchsia_net_policy::{InterfaceInfo, ObserverRequest, ObserverRequestStream},
    fidl_fuchsia_net_stack::StackProxy,
    fuchsia_syslog::fx_log_err,
    fuchsia_zircon as zx,
    futures::lock::Mutex,
    futures::prelude::*,
    std::collections::HashMap,
    std::sync::Arc,
};

const EMPTY: &str = "";

pub async fn serve_fidl_requests(
    stack: StackProxy,
    stream: ObserverRequestStream,
    interface_ids: Arc<Mutex<HashMap<String, u64>>>,
) -> Result<(), fidl::Error> {
    await!(stream.try_for_each(|req| async {
        let interface_ids_lock = await!(interface_ids.lock());
        match req {
            ObserverRequest::ListInterfaces { responder } => {
                let (mut infos, status) = if let Ok(infos) = await!(stack.list_interfaces()) {
                    let infos = infos
                        .into_iter()
                        .filter_map(|info| {
                            match interface_ids_lock.iter().find(|(_name, id)| &&info.id == id) {
                                Some((name, _)) => Some(InterfaceInfo {
                                    name: name.to_owned(),
                                    properties: info.properties,
                                }),

                                None => {
                                    fx_log_err!("faild to find nic {}", info.id,);
                                    Some(InterfaceInfo {
                                        name: EMPTY.to_owned(),
                                        properties: info.properties,
                                    })
                                }
                            }
                        })
                        .collect::<Vec<InterfaceInfo>>();
                    (Some(infos), zx::sys::ZX_OK)
                } else {
                    fx_log_err!("failed to get response from netstack: list_interface");
                    (None, zx::sys::ZX_ERR_INTERNAL)
                };
                responder.send(
                    infos
                        .as_mut()
                        .map(|x| x.iter_mut())
                        .as_mut()
                        .map(|x| x as &mut ExactSizeIterator<Item = &mut InterfaceInfo>),
                    status,
                )
            }
            ObserverRequest::GetInterfaceInfo { name, responder } => {
                let (mut info, status) = if let Some(&id) = interface_ids_lock.get(&name) {
                    if let Ok((info, None)) = await!(stack.get_interface_info(id)) {
                        (
                            Some(InterfaceInfo { name, properties: info.unwrap().properties }),
                            zx::sys::ZX_OK,
                        )
                    } else {
                        (None, zx::sys::ZX_ERR_INTERNAL)
                    }
                } else {
                    (None, zx::sys::ZX_ERR_NOT_FOUND)
                };
                responder.send(info.as_mut().map(OutOfLine), status)
            }
        }
    }))
}

#[cfg(test)]
mod tests {
    use super::*;
    use {
        fidl::endpoints::create_proxy,
        fidl_fuchsia_net_policy::{ObserverMarker, ObserverProxy},
        fidl_fuchsia_net_stack::{
            AdministrativeStatus, InterfaceAddress, PhysicalStatus, StackMarker, StackRequest,
            StackRequestStream,
        },
        fuchsia_async as fasync,
        futures::task::Poll,
        pin_utils::pin_mut,
        std::boxed::Box,
    };

    const ID1: u64 = 1;
    const ID2: u64 = 2;
    const ID3: u64 = 3; // No match in interface_ids
    const NAME1: &str = "lo";
    const NAME2: &str = "eth";
    const UNKNOWN: &str = "";

    fn build_interface_properties() -> fidl_fuchsia_net_stack::InterfaceProperties {
        fidl_fuchsia_net_stack::InterfaceProperties {
            path: "/all/the/way/home".to_owned(),
            mac: Some(Box::new(fidl_fuchsia_hardware_ethernet::MacAddress {
                octets: [0, 1, 2, 255, 254, 253],
            })),
            mtu: 1500,
            features: 2,
            administrative_status: AdministrativeStatus::Enabled,
            physical_status: PhysicalStatus::Up,
            addresses: vec![InterfaceAddress {
                ip_address: fidl_fuchsia_net::IpAddress::Ipv4(fidl_fuchsia_net::Ipv4Address {
                    addr: [1, 1, 1, 1],
                }),
                prefix_len: 4,
            }],
        }
    }

    fn build_interface_info() -> fidl_fuchsia_net_stack::InterfaceInfo {
        fidl_fuchsia_net_stack::InterfaceInfo { id: ID2, properties: build_interface_properties() }
    }

    fn build_no_match_interface_info() -> fidl_fuchsia_net_stack::InterfaceInfo {
        fidl_fuchsia_net_stack::InterfaceInfo { id: ID3, properties: build_interface_properties() }
    }

    fn expect_interface_info() -> fidl_fuchsia_net_policy::InterfaceInfo {
        fidl_fuchsia_net_policy::InterfaceInfo {
            name: NAME2.to_owned(),
            properties: build_interface_properties(),
        }
    }

    fn expect_interface_info_no_match() -> fidl_fuchsia_net_policy::InterfaceInfo {
        fidl_fuchsia_net_policy::InterfaceInfo {
            name: UNKNOWN.to_owned(),
            properties: build_interface_properties(),
        }
    }

    fn setup_interface_tests() -> (fasync::Executor, impl Future, ObserverProxy, StackRequestStream)
    {
        let exec = fasync::Executor::new().expect("failed to create an executor");

        // Set up mock stack fidl server.
        let (stack_proxy, stack_server) =
            create_proxy::<StackMarker>().expect("failed to create stack fidl");
        let stack_stream =
            stack_server.into_stream().expect("failed to create a stack request stream.");

        // Set up real Observer fidl server and client.
        let (observer_proxy, observer_server) =
            create_proxy::<ObserverMarker>().expect("failed to create observer fidl");
        let observer_stream =
            observer_server.into_stream().expect("failed to create an observer request stream.");

        // Create and initialize interface_ids
        let mut interface_ids = HashMap::new();
        interface_ids.insert(NAME1.to_owned(), ID1);
        interface_ids.insert(NAME2.to_owned(), ID2);
        let interface_ids = Arc::new(Mutex::new(interface_ids));

        let observer_service_task =
            serve_fidl_requests(stack_proxy, observer_stream, interface_ids)
                .unwrap_or_else(|e| fx_log_err!("failed to serve observer FIDL call: {}", e));
        (exec, observer_service_task, observer_proxy, stack_stream)
    }

    #[test]
    fn list_interfaces_test() {
        let (mut exec, observer_service_task, observer_proxy, mut stack_stream) =
            setup_interface_tests();

        // Call observer FIDL call.
        let client_fut = observer_proxy.list_interfaces();

        // Let observer client run to stall.
        pin_mut!(client_fut);
        assert!(exec.run_until_stalled(&mut client_fut).is_pending());

        // Let observer server run to stall.
        pin_mut!(observer_service_task);
        assert!(exec.run_until_stalled(&mut observer_service_task).is_pending());

        // Let stack server run to stall and check that we got an appropriate FIDL call.
        let event = match exec.run_until_stalled(&mut stack_stream.next()) {
            Poll::Ready(Some(Ok(req))) => req,
            _ => panic!("Expected a stack fidl call, but there is none!"),
        };

        match event {
            StackRequest::ListInterfaces { responder } => {
                responder
                    .send(&mut vec![build_interface_info()].iter_mut())
                    .expect("failed to send list interface response");
            }
            _ => panic!("Unexpected stack call!"),
        };

        assert!(exec.run_until_stalled(&mut observer_service_task).is_pending());

        // Let observer client run until ready, and check that we got an expected response.
        let (infos, status) = match exec.run_until_stalled(&mut client_fut) {
            Poll::Ready(Ok(req)) => req,
            other => panic!("Expected a response from observer fidl call, but got {:?}!", other),
        };
        assert_eq!(zx::sys::ZX_OK, status);
        assert_eq!(vec![expect_interface_info()], infos.unwrap());
    }

    #[test]
    fn list_interfaces_no_match_test() {
        let (mut exec, observer_service_task, observer_proxy, mut stack_stream) =
            setup_interface_tests();

        // Call observer FIDL call.
        let client_fut = observer_proxy.list_interfaces();

        // Let observer client run to stall.
        pin_mut!(client_fut);
        assert!(exec.run_until_stalled(&mut client_fut).is_pending());

        // Let observer server run to stall.
        pin_mut!(observer_service_task);
        assert!(exec.run_until_stalled(&mut observer_service_task).is_pending());

        // Let stack server run to stall and check that we got an appropriate FIDL call.
        let event = match exec.run_until_stalled(&mut stack_stream.next()) {
            Poll::Ready(Some(Ok(req))) => req,
            _ => panic!("Expected a stack fidl call, but there is none!"),
        };

        match event {
            StackRequest::ListInterfaces { responder } => {
                responder
                    .send(
                        &mut vec![build_interface_info(), build_no_match_interface_info()]
                            .iter_mut(),
                    )
                    .expect("failed to send list interface response");
            }
            _ => panic!("Unexpected stack call!"),
        };

        assert!(exec.run_until_stalled(&mut observer_service_task).is_pending());

        // Let observer client run until ready, and check that we got an expected response.
        let (infos, status) = match exec.run_until_stalled(&mut client_fut) {
            Poll::Ready(Ok(req)) => req,
            other => panic!("Expected a response from observer fidl call, but got {:?}!", other),
        };
        assert_eq!(zx::sys::ZX_OK, status);
        assert_eq!(vec![expect_interface_info(), expect_interface_info_no_match()], infos.unwrap());
    }

    #[test]
    fn get_interface_info_test() {
        let (mut exec, observer_service_task, observer_proxy, mut stack_stream) =
            setup_interface_tests();

        // Call observer FIDL call.
        let client_fut = observer_proxy.get_interface_info(NAME2);

        // Let observer client run to stall.
        pin_mut!(client_fut);
        assert!(exec.run_until_stalled(&mut client_fut).is_pending());

        // Let observer server run to stall.
        pin_mut!(observer_service_task);
        assert!(exec.run_until_stalled(&mut observer_service_task).is_pending());

        // Let stack server run to stall and check that we got an appropriate FIDL call.
        let event = match exec.run_until_stalled(&mut stack_stream.next()) {
            Poll::Ready(Some(Ok(req))) => req,
            _ => panic!("Expected a stack fidl call, but there is none!"),
        };

        match event {
            StackRequest::GetInterfaceInfo { id: _, responder } => {
                responder
                    .send(Some(OutOfLine(&mut build_interface_info())), None)
                    .expect("failed to send list interface response");
            }
            _ => panic!("Unexpected stack call!"),
        };

        assert!(exec.run_until_stalled(&mut observer_service_task).is_pending());

        // Let observer client run until ready, and check that we got an expected response.
        let response = match exec.run_until_stalled(&mut client_fut) {
            Poll::Ready(Ok(req)) => req,
            other => panic!("Expected a response from observer fidl call, but got {:?}", other),
        };
        assert_eq!(expect_interface_info(), *response.0.unwrap());
    }

    #[test]
    fn get_interface_info_not_found_test() {
        let (mut exec, observer_service_task, observer_proxy, mut _stack_stream) =
            setup_interface_tests();

        // Call observer FIDL call.
        let client_fut = observer_proxy.get_interface_info("unknown");

        // Let observer client run to stall.
        pin_mut!(client_fut);
        assert!(exec.run_until_stalled(&mut client_fut).is_pending());

        // Let observer server run to stall.
        pin_mut!(observer_service_task);
        assert!(exec.run_until_stalled(&mut observer_service_task).is_pending());

        // Let observer client run to stall and check that we got an expected response.
        let response = match exec.run_until_stalled(&mut client_fut) {
            Poll::Ready(Ok(req)) => req,
            other => panic!("Expected a response from observer fidl call, but got {:?}", other),
        };

        assert_eq!(zx::Status::NOT_FOUND.into_raw(), response.1);
    }
}
