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

//! LoWPAN Network Tunnel Abstraction
use super::debug::*;
use super::iface::*;
use crate::prelude_internal::*;

use crate::spinel::Subnet;
use anyhow::Error;
use async_trait::async_trait;
use fidl::endpoints::{create_endpoints, create_proxy};
use fidl_fuchsia_hardware_network as fhwnet;
use fidl_fuchsia_net as fnet;
use fidl_fuchsia_net_ext as fnetext;
use fidl_fuchsia_net_interfaces_admin as fnetifadmin;
use fidl_fuchsia_net_interfaces_ext as fnetifext;
use fidl_fuchsia_net_stack as fnetstack;
use fidl_fuchsia_net_stack_ext::FidlReturn as _;
use fidl_fuchsia_net_tun as ftun;
use fuchsia_component::client::{connect_channel_to_protocol, connect_to_protocol};
use fuchsia_zircon as zx;
use futures::stream::BoxStream;
use parking_lot::Mutex;
use std::convert::TryInto;
use std::net::{Ipv6Addr, UdpSocket};

const IPV6_MIN_MTU: u32 = 1280;
const TUN_PORT_ID: u8 = 0;

#[derive(Debug)]
pub struct TunNetworkInterface {
    tun_dev: ftun::DeviceProxy,
    tun_port: ftun::PortProxy,
    #[allow(unused)] // TODO (fxb/64704): use `control` after converting methods to async.
    control: fnetifext::admin::Control,
    control_sync: Mutex<fnetifadmin::ControlSynchronousProxy>,
    stack_sync: Mutex<fnetstack::StackSynchronousProxy>,
    mcast_socket: UdpSocket,
    id: u64,
}

impl TunNetworkInterface {
    pub async fn try_new(name: Option<String>) -> Result<TunNetworkInterface, Error> {
        let tun_control = connect_to_protocol::<ftun::ControlMarker>()?;

        let (tun_dev, req) = create_proxy::<ftun::DeviceMarker>()?;

        tun_control
            .create_device(
                ftun::DeviceConfig { blocking: Some(true), ..ftun::DeviceConfig::EMPTY },
                req,
            )
            .context("failed to create tun pair")?;

        let (tun_port, port_req) = create_proxy::<ftun::PortMarker>()?;
        tun_dev
            .add_port(
                ftun::DevicePortConfig {
                    base: Some(ftun::BasePortConfig {
                        id: Some(TUN_PORT_ID),
                        mtu: Some(IPV6_MIN_MTU),
                        rx_types: Some(vec![
                            fhwnet::FrameType::Ipv6,
                            // TODO(fxbug.dev/64292): Remove this once netstack doesn't require it.
                            fhwnet::FrameType::Ipv4,
                        ]),
                        tx_types: Some(vec![
                            fhwnet::FrameTypeSupport {
                                type_: fhwnet::FrameType::Ipv6,
                                features: fhwnet::FRAME_FEATURES_RAW,
                                supported_flags: fhwnet::TxFlags::empty(),
                            },
                            // TODO(fxbug.dev/64292): Remove this once netstack doesn't require it.
                            fhwnet::FrameTypeSupport {
                                type_: fhwnet::FrameType::Ipv4,
                                features: fhwnet::FRAME_FEATURES_RAW,
                                supported_flags: fhwnet::TxFlags::empty(),
                            },
                        ]),
                        ..ftun::BasePortConfig::EMPTY
                    }),
                    ..ftun::DevicePortConfig::EMPTY
                },
                port_req,
            )
            .context("failed to add device port")?;

        let (device, device_req) = create_endpoints::<fhwnet::DeviceMarker>()?;

        tun_dev.get_device(device_req).context("get device failed")?;

        let (control, control_sync) = {
            let installer = connect_to_protocol::<fnetifadmin::InstallerMarker>()?;
            let (device_control, server_end) = create_proxy::<fnetifadmin::DeviceControlMarker>()?;
            installer.install_device(device, server_end).context("install_device failed")?;
            // Interface lifetime is already tied to us because of tun device,
            // no need to keep this extra channel around.
            device_control.detach().context("device control detach failed")?;

            let (port, server_end) = create_proxy::<fhwnet::PortMarker>()?;
            tun_port.get_port(server_end).context("get_port failed")?;
            let mut port_id = port
                .get_info()
                .await
                .context("get_info failed")?
                .id
                .ok_or_else(|| anyhow::anyhow!("port id missing from info"))?;

            let (control_sync_client_channel, control_sync_server) = zx::Channel::create()?;
            let control_sync =
                fnetifadmin::ControlSynchronousProxy::new(control_sync_client_channel);
            device_control
                .create_interface(
                    &mut port_id,
                    control_sync_server.into(),
                    fnetifadmin::Options { name: name.clone(), ..fnetifadmin::Options::EMPTY },
                )
                .context("create_interface failed")?;

            let (control, server_end) = fnetifext::admin::Control::create_endpoints()?;
            device_control
                .create_interface(
                    &mut port_id,
                    server_end,
                    fnetifadmin::Options { name, ..fnetifadmin::Options::EMPTY },
                )
                .context("create_interface failed")?;

            (control, Mutex::new(control_sync))
        };

        let id = control_sync.lock().get_id(zx::Time::INFINITE).context("get_id failed")?;
        let _was_disabled: bool = control_sync
            .lock()
            .enable(zx::Time::INFINITE)
            .context("enable error")?
            .map_err(|e| anyhow::anyhow!("enable failed {:?}", e))?;

        let (client, server) = zx::Channel::create()?;
        connect_channel_to_protocol::<fnetstack::StackMarker>(server)?;
        let stack_sync = Mutex::new(fnetstack::StackSynchronousProxy::new(client));
        let mcast_socket = UdpSocket::bind((Ipv6Addr::LOCALHOST, 0)).context("UdpSocket::bind")?;

        Ok(TunNetworkInterface {
            tun_dev,
            tun_port,
            control,
            control_sync,
            stack_sync,
            mcast_socket,
            id,
        })
    }
}

#[async_trait]
impl NetworkInterface for TunNetworkInterface {
    fn get_index(&self) -> u64 {
        self.id
    }

    async fn outbound_packet_from_stack(&self) -> Result<Vec<u8>, Error> {
        let frame = self
            .tun_dev
            .read_frame()
            .await
            .context("FIDL error on read_frame")?
            .map_err(fuchsia_zircon::Status::from_raw)
            .context("Error calling read_frame")?;

        if let Some(packet) = frame.data.as_ref() {
            fx_log_trace!(
                "TunNetworkInterface: Packet arrived from stack: {:?}",
                Ipv6PacketDebug(packet)
            );
        }

        Ok(frame.data.ok_or(format_err!("data field was absent"))?)
    }

    async fn inbound_packet_to_stack(&self, packet: &[u8]) -> Result<(), Error> {
        fx_log_trace!("TunNetworkInterface: Packet sent to stack: {:?}", Ipv6PacketDebug(packet));

        Ok(self
            .tun_dev
            .write_frame(ftun::Frame {
                port: Some(TUN_PORT_ID),
                frame_type: Some(fhwnet::FrameType::Ipv6),
                data: Some(packet.to_vec()),
                meta: None,
                ..fidl_fuchsia_net_tun::Frame::EMPTY
            })
            .await?
            .map_err(fuchsia_zircon::Status::from_raw)?)
    }

    async fn set_online(&self, online: bool) -> Result<(), Error> {
        fx_log_info!("TunNetworkInterface: Interface online: {:?}", online);

        if online {
            self.tun_port.set_online(true).await?;
            let _was_disabled: bool = self
                .control_sync
                .lock()
                .enable(zx::Time::INFINITE)
                .context("enable error")?
                .map_err(|e| anyhow::anyhow!("enable failed {:?}", e))?;
        } else {
            self.tun_port.set_online(false).await?;
        }

        Ok(())
    }

    async fn set_enabled(&self, enabled: bool) -> Result<(), Error> {
        fx_log_info!("TunNetworkInterface: Interface enabled: {:?}", enabled);
        if enabled {
            let _was_disabled: bool = self
                .control_sync
                .lock()
                .enable(zx::Time::INFINITE)
                .context("enable error")?
                .map_err(|e| anyhow::anyhow!("enable failed {:?}", e))?;
        } else {
            let _was_enabled: bool = self
                .control_sync
                .lock()
                .disable(zx::Time::INFINITE)
                .context("disable error")?
                .map_err(|e| anyhow::anyhow!("disable failed {:?}", e))?;
        }
        Ok(())
    }

    fn add_address(&self, addr: &Subnet) -> Result<(), Error> {
        fx_log_info!("TunNetworkInterface: Adding Address: {:?}", addr);
        let mut device_addr = fnet::Subnet {
            addr: fnetext::IpAddress(addr.addr.into()).into(),
            prefix_len: addr.prefix_len,
        };
        let (address_state_provider, server_end) = fidl::endpoints::create_proxy::<
            fidl_fuchsia_net_interfaces_admin::AddressStateProviderMarker,
        >()
        .expect("create proxy");
        address_state_provider.detach()?;

        self.control_sync.lock().add_address(
            &mut device_addr,
            fidl_fuchsia_net_interfaces_admin::AddressParameters::EMPTY,
            server_end,
        )?;

        let mut forwarding_entry = fnetstack::ForwardingEntry {
            subnet: fnetext::apply_subnet_mask(fnet::Subnet {
                addr: fnetext::IpAddress(addr.addr.into()).into(),
                prefix_len: addr.prefix_len,
            }),
            device_id: self.id,
            next_hop: None,
            metric: 0,
        };
        self.stack_sync
            .lock()
            .add_forwarding_entry(&mut forwarding_entry, zx::Time::INFINITE)?
            .expect("add_forwarding_entry");

        fx_log_info!("TunNetworkInterface: Successfully added address {:?}", addr);
        Ok(())
    }

    fn remove_address(&self, addr: &Subnet) -> Result<(), Error> {
        fx_log_info!("TunNetworkInterface: Removing Address: {:?}", addr);
        let mut device_addr = fnet::Subnet {
            addr: fnetext::IpAddress(addr.addr.into()).into(),
            prefix_len: addr.prefix_len,
        };
        let mut forwarding_entry = fnetstack::ForwardingEntry {
            subnet: fnetext::apply_subnet_mask(fnet::Subnet {
                addr: fnetext::IpAddress(addr.addr.into()).into(),
                prefix_len: addr.prefix_len,
            }),
            device_id: self.id,
            next_hop: None,
            metric: 0,
        };

        self.stack_sync
            .lock()
            .del_forwarding_entry(&mut forwarding_entry, zx::Time::INFINITE)
            .squash_result()?;

        self.control_sync
            .lock()
            .remove_address(&mut device_addr, zx::Time::INFINITE)?
            .expect("control_sync.remove_address");
        fx_log_info!("TunNetworkInterface: Successfully removed address {:?}", addr);
        Ok(())
    }

    fn add_external_route(&self, addr: &Subnet) -> Result<(), Error> {
        fx_log_info!("TunNetworkInterface: Adding external route: {:?} (CURRENTLY IGNORED)", addr);
        Ok(())
    }

    fn remove_external_route(&self, addr: &Subnet) -> Result<(), Error> {
        fx_log_info!(
            "TunNetworkInterface: Removing external route: {:?} (CURRENTLY IGNORED)",
            addr
        );
        Ok(())
    }

    /// Has the interface join the given multicast group.
    fn join_mcast_group(&self, addr: &std::net::Ipv6Addr) -> Result<(), Error> {
        fx_log_info!("TunNetworkInterface: Joining multicast group: {:?}", addr);
        self.mcast_socket.join_multicast_v6(addr, self.id.try_into().unwrap())?;
        Ok(())
    }

    /// Has the interface leave the given multicast group.
    fn leave_mcast_group(&self, addr: &std::net::Ipv6Addr) -> Result<(), Error> {
        fx_log_info!("TunNetworkInterface: Leaving multicast group: {:?}", addr);
        self.mcast_socket.leave_multicast_v6(addr, self.id.try_into().unwrap())?;
        Ok(())
    }

    fn take_event_stream(&self) -> BoxStream<'_, Result<NetworkInterfaceEvent, Error>> {
        let enabled_stream = futures::stream::try_unfold((), move |()| async move {
            loop {
                if let ftun::InternalState { has_session: Some(has_session), .. } =
                    self.tun_port.watch_state().await?
                {
                    break Ok(Some((
                        NetworkInterfaceEvent::InterfaceEnabledChanged(has_session),
                        (),
                    )));
                }
            }
        });

        use fidl_fuchsia_net_interfaces::*;
        use std::convert::TryInto;

        struct EventState {
            prev_prop: Properties,
            watcher: Option<WatcherProxy>,
            next_events: Vec<NetworkInterfaceEvent>,
        }
        let init_state =
            EventState { prev_prop: Properties::EMPTY, watcher: None, next_events: Vec::default() };

        let if_event_stream = futures::stream::try_unfold(init_state, move |mut state| {
            async move {
                if state.watcher.is_none() {
                    let fnif_state = connect_to_protocol::<StateMarker>()?;
                    let (watcher, req) = create_proxy::<WatcherMarker>()?;
                    fnif_state.get_watcher(WatcherOptions::EMPTY, req)?;
                    state.watcher = Some(watcher);
                }

                loop {
                    // Flush out any pending events
                    if let Some(event) = state.next_events.pop() {
                        return Ok(Some((event, state)));
                    }

                    match state.watcher.as_ref().unwrap().watch().await? {
                        Event::Existing(prop) if prop.id == Some(self.id) => {
                            assert!(
                                state.prev_prop.id == None,
                                "Got Event::Existing twice for same interface"
                            );
                            state.prev_prop = prop;
                            continue;
                        }
                        Event::Idle(_) => {
                            if state.prev_prop.id == None {
                                return Err(format_err!("Interface no longer exists"));
                            }
                        }
                        Event::Removed(id) if id == self.id => return Ok(None),

                        Event::Changed(prop) if prop.id == Some(self.id) => {
                            assert!(state.prev_prop.id.is_some());

                            traceln!("TunNetworkInterface: Got Event::Changed({:#?})", prop);

                            if let Some(addrs) = prop.addresses.as_ref() {
                                let empty_addrs = vec![];
                                let prev_addrs =
                                    state.prev_prop.addresses.as_ref().unwrap_or(&empty_addrs);
                                state.next_events.extend(
                                    addrs.iter().filter(|x| !prev_addrs.contains(x)).filter_map(
                                        |Address { addr, valid_until: _, .. }| {
                                            addr.unwrap()
                                                .try_into()
                                                .ok()
                                                .map(NetworkInterfaceEvent::AddressWasAdded)
                                        },
                                    ),
                                );
                                state.next_events.extend(
                                    prev_addrs.iter().filter(|x| !addrs.contains(x)).filter_map(
                                        |Address { addr, valid_until: _, .. }| {
                                            addr.unwrap()
                                                .try_into()
                                                .ok()
                                                .map(NetworkInterfaceEvent::AddressWasRemoved)
                                        },
                                    ),
                                );
                            }

                            traceln!(
                                "TunNetworkInterface: Queued events: {:#?}",
                                state.next_events
                            );

                            state.prev_prop = prop;
                        }

                        _ => continue,
                    }
                }
            }
        });

        futures::stream::select(enabled_stream, if_event_stream).boxed()
    }

    async fn set_ipv6_forwarding_enabled(&self, enabled: bool) -> Result<(), Error> {
        // Ignore the configuration before our change was applied.
        let _: fnetifadmin::Configuration = self
            .control_sync
            .lock()
            .set_configuration(
                fnetifadmin::Configuration {
                    ipv6: Some(fnetifadmin::Ipv6Configuration {
                        forwarding: Some(enabled),
                        ..fnetifadmin::Ipv6Configuration::EMPTY
                    }),
                    ..fnetifadmin::Configuration::EMPTY
                },
                zx::Time::INFINITE,
            )
            .map_err(anyhow::Error::new)
            .and_then(|res| {
                res.map_err(|e: fnetifadmin::ControlSetConfigurationError| {
                    anyhow::anyhow!("{:?}", e)
                })
            })
            .context("set configuration")?;

        Ok(())
    }
}
