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

//! The special-purpose event loop used by the network manager.
//!
//! This event loop takes in events from Admin and State FIDL,
//! and implements handlers for FIDL calls.
//!
//! This is implemented with a single mpsc queue for all event types - `EventLoop` holds the
//! consumer, and any event handling that requires state within `EventLoop` holds a producer,
//! allowing it to delegate work to the `EventLoop` by sending a message. In this documentation, we
//! call anything that holds a producer a "worker".
//!
//! Having a single queue for all of the message types is beneficial, since in guarantees a FIFO
//! ordering for all messages - whichever messages arrive first, will be handled first.
//!
//! We'll look at each type of message, to see how each one is handled - starting with FIDL
//! messages, since they can be thought of as the entrypoint for the whole loop (as nothing happens
//! until a FIDL call is made).
//!
//! # FIDL Worker
//!
//! The FIDL part of the event loop implements the fuchsia.router.config Admin and State
//! interfaces. The type of the event loop message for a FIDL call is
//! simply the generated FIDL type. When the event loop starts up, we use `fuchsia_app` to start a
//! FIDL server that simply sends all of the events it receives to the event loop (via the sender
//! end of the mpsc queue). When `EventLoop` receives this message, it calls the
//! `handle_fidl_router_admin_request` or `handle_fidl_router_state_request` method, which,
//! depending on what the request is, either:
//!
//! * Responds with the requested information.
//! * Modifies the router state byt accessinc netcfg.
//! * Updates local state.

use failure::{bail, Error, ResultExt};
use fidl_fuchsia_router_config::RouterAdminRequest;
use fidl_fuchsia_router_config::{Id, Lif, Port};
use fidl_fuchsia_router_config::{RouterStateGetPortsResponder, RouterStateRequest};
use futures::channel::mpsc;
use futures::prelude::*;
use network_manager_core::{
    hal::NetCfg, lifmgr::LIFType, packet_filter::PacketFilter, portmgr::PortId, DeviceState,
};

macro_rules! router_error {
    ($code:ident, $desc:expr) => {
        Some(fidl::encoding::OutOfLine(&mut fidl_fuchsia_router_config::Error {
            code: fidl_fuchsia_router_config::ErrorCode::$code,
            description: $desc,
        }))
    };
}

macro_rules! not_supported {
    () => {
        router_error!(NotSupported, None)
    };
}
macro_rules! not_found {
    () => {
        router_error!(NotFound, None)
    };
}
macro_rules! internal_error {
    ($s:expr) => {
        router_error!(Internal, Some($s.to_string()))
    };
}

/// The events that can trigger an action in the event loop.
pub enum Event {
    /// A request from the fuchsia.router.config Admin FIDL interface
    FidlRouterAdminEvent(RouterAdminRequest),
    /// A request from the fuchsia.router.config State FIDL interface
    FidlRouterStateEvent(RouterStateRequest),
    /// fuchsia.net.stack.StackEvent
    StackObservable(<fidl_fuchsia_net_stack::StackEventStream as futures::Stream>::Item),
}

/// The event loop.
pub struct EventLoop {
    event_recv: Option<mpsc::UnboundedReceiver<Event>>,
    device: DeviceState,
}

impl EventLoop {
    pub fn new() -> Result<Self, Error> {
        let (event_send, event_recv) = futures::channel::mpsc::unbounded::<Event>();
        let fidl_worker = crate::fidl_worker::FidlWorker;
        let _ = fidl_worker.spawn(event_send.clone());
        let overnet_worker = crate::overnet_worker::OvernetWorker;
        let _r = overnet_worker.spawn(event_send.clone());
        let netcfg = NetCfg::new()?;
        let packet_filter = PacketFilter::start()
            .context("network_manager failed to start packet filter!")
            .unwrap();

        Ok(EventLoop {
            event_recv: Some(event_recv),
            device: DeviceState::new(netcfg, packet_filter),
        })
    }

    pub async fn run(mut self) -> Result<(), Error> {
        self.device.populate_state().await?;
        let mut select_stream = futures::stream::select(
            self.event_recv.take().unwrap(),
            self.device.take_event_stream().map(|e| Event::StackObservable(e)),
        );

        loop {
            match select_stream.next().await {
                Some(Event::FidlRouterAdminEvent(req)) => {
                    self.handle_fidl_router_admin_request(req).await;
                }
                Some(Event::FidlRouterStateEvent(req)) => {
                    self.handle_fidl_router_state_request(req).await;
                }
                Some(Event::StackObservable(event)) => self.handle_stack_event(event).await,
                None => bail!("Stream of events ended unexpectedly"),
            }
        }
    }

    async fn handle_stack_event(
        &mut self,
        event: <fidl_fuchsia_net_stack::StackEventStream as futures::Stream>::Item,
    ) {
        match event {
            Ok(e) => self.device.update_state_for_stack_event(e).await,
            Err(e) => warn!("error from stack observer: {:?}", e),
        }
    }

    async fn handle_fidl_router_admin_request(&mut self, req: RouterAdminRequest) {
        match req {
            RouterAdminRequest::CreateWan { name, vlan, ports, responder } => {
                let r = self
                    .fidl_create_lif(
                        LIFType::WAN,
                        name,
                        vlan,
                        ports.iter().map(|x| PortId::from(*x as u64)).collect(),
                    )
                    .await;
                match r {
                    Ok(mut id) => responder.send(Some(fidl::encoding::OutOfLine(&mut id)), None),
                    Err(mut e) => responder.send(None, Some(fidl::encoding::OutOfLine(&mut e))),
                }
            }
            RouterAdminRequest::CreateLan { name, vlan, ports, responder } => {
                let r = self
                    .fidl_create_lif(
                        LIFType::LAN,
                        name,
                        vlan,
                        ports.iter().map(|x| PortId::from(*x as u64)).collect(),
                    )
                    .await;
                match r {
                    Ok(mut id) => responder.send(Some(fidl::encoding::OutOfLine(&mut id)), None),
                    Err(mut e) => responder.send(None, Some(fidl::encoding::OutOfLine(&mut e))),
                }
            }
            RouterAdminRequest::RemoveWan { wan_id, responder } => {
                let mut r = self.fidl_delete_lif(wan_id).await;
                responder.send(r.as_mut().map(fidl::encoding::OutOfLine)).or_else(|e| {
                    error!("Error sending response: {:?}", e);
                    Err(e)
                })
            }
            RouterAdminRequest::RemoveLan { lan_id, responder } => {
                let mut r = self.fidl_delete_lif(lan_id).await;
                responder.send(r.as_mut().map(fidl::encoding::OutOfLine)).or_else(|e| {
                    error!("Error sending response: {:?}", e);
                    Err(e)
                })
            }
            RouterAdminRequest::SetWanProperties { wan_id, properties, responder } => {
                if self
                    .device
                    .update_lif_properties(
                        u128::from_ne_bytes(wan_id.uuid),
                        fidl_fuchsia_router_config::LifProperties::Wan(properties),
                    )
                    .await
                    .is_err()
                {
                    warn!("WAN {:?} found but failed to update properties", wan_id);
                    responder.send(not_found!())
                } else {
                    info!("WAN properties updated");
                    responder.send(None)
                }
            }
            RouterAdminRequest::SetLanProperties { lan_id, properties, responder } => {
                if self
                    .device
                    .update_lif_properties(
                        u128::from_ne_bytes(lan_id.uuid),
                        fidl_fuchsia_router_config::LifProperties::Lan(properties),
                    )
                    .await
                    .is_err()
                {
                    warn!("failed to update LAN properties");
                    responder.send(not_found!())
                } else {
                    info!("LAN properties updated");
                    responder.send(None)
                }
            }
            RouterAdminRequest::SetDhcpServerOptions { lan_id, options, responder } => {
                info!("{:?}, {:?}", lan_id, options);
                responder.send(not_supported!())
            }
            RouterAdminRequest::SetDhcpAddressPool { lan_id, pool, responder } => {
                info!("{:?}, {:?}", lan_id, pool);
                responder.send(not_supported!())
            }
            RouterAdminRequest::SetDhcpReservation { lan_id, reservation, responder } => {
                info!("{:?}, {:?}", lan_id, reservation);
                responder.send(None, not_supported!())
            }
            RouterAdminRequest::DeleteDhcpReservation { reservation_id, responder } => {
                info!("{:?}", reservation_id);
                responder.send(not_supported!())
            }
            RouterAdminRequest::SetDnsResolver { config, responder } => {
                info!("{:?}", config);
                responder.send(None, not_supported!())
            }
            RouterAdminRequest::SetDnsForwarder { config, responder } => {
                info!("{:?}", config);
                responder.send(not_supported!())
            }
            RouterAdminRequest::AddDnsEntry { entry, responder } => {
                info!("{:?}", entry);
                responder.send(None, not_supported!())
            }
            RouterAdminRequest::DeleteDnsEntry { entry_id, responder } => {
                info!("{:?}", entry_id);
                responder.send(not_supported!())
            }
            RouterAdminRequest::SetRoute { route, responder } => {
                info!("{:?}", route);
                responder.send(None, not_supported!())
            }
            RouterAdminRequest::UpdateRouteMetric { route_id, metric, responder } => {
                info!("{:?} {:?}", route_id, metric);
                responder.send(not_supported!())
            }
            RouterAdminRequest::DeleteRoute { route_id, responder } => {
                info!("{:?}", route_id);
                responder.send(not_supported!())
            }
            RouterAdminRequest::SetSecurityFeatures { features, responder } => {
                info!("{:?}", features);
                responder.send(not_supported!())
            }
            RouterAdminRequest::SetPortForward { rule, responder } => {
                info!("{:?}", rule);
                responder.send(None, not_supported!())
            }
            RouterAdminRequest::DeletePortForward { rule_id, responder } => {
                info!("{:?}", rule_id);
                responder.send(not_supported!())
            }
            RouterAdminRequest::SetPortTrigger { rule, responder } => {
                info!("{:?}", rule);
                responder.send(None, not_supported!())
            }
            RouterAdminRequest::DeletePortTrigger { rule_id, responder } => {
                info!("{:?}", rule_id);
                responder.send(not_supported!())
            }
            RouterAdminRequest::SetFilter { rule, responder } => {
                let r = self
                    .device
                    .set_filter(rule)
                    .await
                    .context("Error installing new packet filter rule");
                match r {
                    Ok(()) => responder.send(None, None),
                    Err(e) => responder.send(None, internal_error!(e.to_string())),
                }
            }
            RouterAdminRequest::DeleteFilter { rule_id, responder } => {
                info!("{:?}", rule_id);
                responder.send(not_supported!())
            }
            RouterAdminRequest::SetIpv6PinHole { rule, responder } => {
                info!("{:?}", rule);
                responder.send(None, not_supported!())
            }
            RouterAdminRequest::DeleteIpv6PinHole { rule_id, responder } => {
                info!("{:?}", rule_id);
                responder.send(not_supported!())
            }
            RouterAdminRequest::SetDmzHost { rule, responder } => {
                info!("{:?}", rule);
                responder.send(None, not_supported!())
            }
            RouterAdminRequest::DeleteDmzHost { rule_id, responder } => {
                info!("{:?}", rule_id);
                responder.send(not_supported!())
            }
            RouterAdminRequest::SetSystemConfig { config, responder } => {
                info!("{:?}", config);
                responder.send(None, not_supported!())
            }
            RouterAdminRequest::CreateWlanNetwork { network: _, responder } => {
                // TODO(guzt): implement
                responder.send(None, not_supported!())
            }
            RouterAdminRequest::DeleteWlanNetwork { network_id: _, responder } => {
                // TODO(guzt): implement
                responder.send(not_supported!())
            }
        }
        .unwrap_or_else(|e| error!("Error sending response {}", e))
    }

    async fn fidl_create_lif(
        &mut self,
        lif_type: LIFType,
        name: String,
        vlan: u16,
        ports: Vec<PortId>,
    ) -> Result<Id, fidl_fuchsia_router_config::Error> {
        let lif = self.device.create_lif(lif_type, name, vlan, ports).await;
        match lif {
            Err(e) => {
                error!("Error creating lif {:?}", e);
                Err(fidl_fuchsia_router_config::Error {
                    code: fidl_fuchsia_router_config::ErrorCode::AlreadyExists,
                    description: None,
                })
            }
            Ok(l) => {
                let i = l.id();
                Ok(Id { uuid: i.uuid().to_ne_bytes(), version: i.version() })
            }
        }
    }

    async fn fidl_delete_lif(&mut self, id: Id) -> Option<fidl_fuchsia_router_config::Error> {
        let lif = self.device.delete_lif(u128::from_ne_bytes(id.uuid)).await;
        match lif {
            Err(e) => {
                error!("Error deleting lif {:?}", e);
                Some(fidl_fuchsia_router_config::Error {
                    code: fidl_fuchsia_router_config::ErrorCode::NotFound,
                    description: None,
                })
            }
            Ok(()) => None,
        }
    }

    async fn handle_fidl_router_state_request(&mut self, req: RouterStateRequest) {
        match req {
            RouterStateRequest::GetWanPorts { wan_id, responder } => {
                let lif = self.device.lif(u128::from_ne_bytes(wan_id.uuid));
                match lif {
                    None => {
                        warn!("WAN {:?} not found", wan_id);
                        responder.send(&mut None.into_iter(), not_found!())
                    }
                    Some(l) => responder.send(&mut l.ports().map(|p| p.to_u32()), None),
                }
            }
            RouterStateRequest::GetLanPorts { lan_id, responder } => {
                let lif = self.device.lif(u128::from_ne_bytes(lan_id.uuid));
                match lif {
                    None => {
                        warn!("LAN {:?} not found", lan_id);
                        responder.send(&mut None.into_iter(), not_found!())
                    }
                    Some(l) => responder.send(&mut l.ports().map(|p| p.to_u32()), None),
                }
            }
            RouterStateRequest::GetWan { wan_id, responder } => {
                let lif = self.device.lif(u128::from_ne_bytes(wan_id.uuid));
                info!("lifs {:?}", lif);
                match lif {
                    None => {
                        warn!("WAN {:?} not found", wan_id);
                        responder.send(
                            fidl_fuchsia_router_config::Lif {
                                element: None,
                                name: None,
                                port_ids: None,
                                properties: None,
                                vlan: None,
                                type_: None,
                            },
                            not_found!(),
                        )
                    }
                    Some(l) => {
                        let ll = l.to_fidl_lif();
                        responder.send(ll, None)
                    }
                }
            }
            RouterStateRequest::GetLan { lan_id, responder } => {
                let lif = self.device.lif(u128::from_ne_bytes(lan_id.uuid));
                match lif {
                    None => {
                        warn!("LAN {:?} not found", lan_id);
                        responder.send(
                            fidl_fuchsia_router_config::Lif {
                                element: None,
                                name: None,
                                port_ids: None,
                                properties: None,
                                vlan: None,
                                type_: None,
                            },
                            not_found!(),
                        )
                    }
                    Some(l) => {
                        let ll = l.to_fidl_lif();
                        responder.send(ll, None)
                    }
                }
            }
            RouterStateRequest::GetWans { responder } => {
                let lifs: Vec<Lif> =
                    self.device.lifs(LIFType::WAN).map(|l| l.to_fidl_lif()).collect();
                info!("result: {:?} ", lifs);
                responder.send(&mut lifs.into_iter())
            }
            RouterStateRequest::GetLans { responder } => {
                let lifs: Vec<Lif> =
                    self.device.lifs(LIFType::LAN).map(|l| l.to_fidl_lif()).collect();
                info!("result: {:?} ", lifs);
                responder.send(&mut lifs.into_iter())
            }
            RouterStateRequest::GetWanProperties { wan_id, responder } => {
                info!("{:?}", wan_id);
                let properties = fidl_fuchsia_router_config::WanProperties {
                    connection_type: None,
                    connection_parameters: None,
                    address_method: None,
                    address_v4: None,
                    gateway_v4: None,
                    connection_v6_mode: None,
                    address_v6: None,
                    gateway_v6: None,
                    hostname: None,
                    clone_mac: None,
                    mtu: None,
                    enable: None,
                    metric: None,
                };
                responder.send(properties, not_supported!())
            }
            RouterStateRequest::GetLanProperties { lan_id, responder } => {
                info!("{:?}", lan_id);
                let properties = fidl_fuchsia_router_config::LanProperties {
                    address_v4: None,
                    enable_dhcp_server: None,
                    dhcp_config: None,
                    address_v6: None,
                    enable_dns_forwarder: None,
                    enable: None,
                };

                responder.send(properties, not_supported!())
            }
            RouterStateRequest::GetDhcpConfig { lan_id, responder } => {
                info!("{:?}", lan_id);
                responder.send(None, not_supported!())
            }
            RouterStateRequest::GetDnsResolver { responder } => {
                let mut resolver = fidl_fuchsia_router_config::DnsResolverConfig {
                    element: Id {
                        uuid: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
                        version: 0,
                    },
                    policy: fidl_fuchsia_router_config::DnsPolicy::NotSet,
                    search: fidl_fuchsia_router_config::DnsSearch {
                        domain_name: None,
                        servers: vec![],
                    },
                };
                responder.send(&mut resolver)
            }
            RouterStateRequest::GetDnsForwarder { responder } => {
                let config = fidl_fuchsia_router_config::DnsForwarderConfig {
                    element: Id {
                        uuid: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
                        version: 0,
                    },
                    search: fidl_fuchsia_router_config::DnsSearch {
                        domain_name: None,
                        servers: vec![],
                    },
                };
                let mut forwarder = fidl_fuchsia_router_config::DnsForwarder {
                    config: config,
                    interfaces: vec![],
                    resolver: vec![],
                };
                responder.send(&mut forwarder)
            }
            RouterStateRequest::GetRoutes { responder } => responder.send(&mut [].iter_mut()),
            RouterStateRequest::GetRoute { route_id, responder } => {
                info!("{:?}", route_id);
                responder.send(None, not_supported!())
            }
            RouterStateRequest::GetSecurityFeatures { responder } => {
                let security = fidl_fuchsia_router_config::SecurityFeatures {
                    allow_multicast: None,
                    drop_icmp_echo: None,
                    firewall: None,
                    h323_passthru: None,
                    ipsec_passthru: None,
                    l2_tp_passthru: None,
                    nat: None,
                    pptp_passthru: None,
                    rtsp_passthru: None,
                    sip_passthru: None,
                    upnp: None,
                    v6_firewall: None,
                };
                responder.send(security)
            }
            RouterStateRequest::GetPortForwards { responder } => responder.send(&mut [].iter_mut()),
            RouterStateRequest::GetPortForward { rule_id, responder } => {
                info!("{:?}", rule_id);
                responder.send(None, not_supported!())
            }
            RouterStateRequest::GetPorts { responder } => {
                self.fidl_get_ports(responder).await;
                Ok(())
            }
            RouterStateRequest::GetPort { port_id, responder } => {
                info!("{:?}", port_id);
                responder.send(None, not_supported!())
            }
            RouterStateRequest::GetPortTrigger { rule_id, responder } => {
                info!("{:?}", rule_id);
                responder.send(None, not_supported!())
            }
            RouterStateRequest::GetPortTriggers { responder } => responder.send(&mut [].iter_mut()),
            RouterStateRequest::GetFilter { rule_id, responder } => {
                info!("{:?}", rule_id);
                responder.send(None, not_supported!())
            }
            RouterStateRequest::GetFilters { responder } => {
                let result = self.device.get_filters().await.context("Error getting filters");
                let mut filter_rules = Vec::new();
                match result {
                    Ok(f) => {
                        filter_rules = f.into_iter().collect();
                        info!("Filter rules returned: {:?}", filter_rules.len());
                    }
                    Err(e) => error!("Failed parsing filter rules: {}", e),
                }
                responder.send(&mut filter_rules.iter_mut())
            }
            RouterStateRequest::GetIpv6PinHole { rule_id, responder } => {
                info!("{:?}", rule_id);
                responder.send(None, not_supported!())
            }
            RouterStateRequest::GetIpv6PinHoles { responder } => responder.send(&mut [].iter_mut()),
            RouterStateRequest::GetDmzHost { rule_id, responder } => {
                info!("{:?}", rule_id);
                responder.send(None, not_supported!())
            }
            RouterStateRequest::GetSystemConfig { responder } => {
                let config = fidl_fuchsia_router_config::SystemConfig {
                    element: None,
                    timezone: None,
                    daylight_savings_time_enabled: None,
                    leds_enabled: None,
                    hostname: None,
                };
                responder.send(config)
            }
            RouterStateRequest::GetDevice { responder } => {
                let device = fidl_fuchsia_router_config::Device {
                    version: None,
                    topology: None,
                    config: None,
                };
                responder.send(device)
            }
            RouterStateRequest::GetWlanNetworks { responder } => {
                responder.send(&mut vec![].into_iter())
            }
            RouterStateRequest::GetRadios { responder } => responder.send(&mut vec![].into_iter()),
        }
        .unwrap_or_else(|e| error!("Error sending response {}", e))
    }

    async fn fidl_get_ports(&mut self, responder: RouterStateGetPortsResponder) {
        let ps = self.device.ports();
        let mut ports: Vec<Port> = ps
            .map(|p| Port {
                element: Id { uuid: p.e_id.uuid().to_ne_bytes(), version: p.e_id.version() },
                id: p.port_id.to_u32(),
                path: p.path.clone(),
            })
            .collect();
        responder.send(&mut ports.iter_mut()).context("Error sending a response").unwrap();
    }
}
