// 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 std::collections::hash_map::HashMap;

use ethernet as eth;
use fidl_fuchsia_hardware_ethernet::Features;
use net_types::{ethernet::Mac, UnicastAddr};
use netstack3_core::{DeviceId, Entry, IdMapCollection, IdMapCollectionKey};

pub const LOOPBACK_MAC: Mac = Mac::new([0, 0, 0, 0, 0, 0]);

pub type BindingId = u64;

/// Keeps tabs on devices.
///
/// `Devices` keeps a list of devices that are installed in the netstack with
/// an associated netstack core ID `C` used to reference the device.
///
/// The type parameters `C` and `I` are for the core ID type and the extra
/// information associated with the device, respectively, and default to the
/// types used by `EventLoop` for brevity in the main use case. The type
/// parameters are there to allow testing without dependencies on `core`.
pub struct Devices<C: IdMapCollectionKey = DeviceId, I = DeviceSpecificInfo> {
    devices: IdMapCollection<C, DeviceInfo<C, I>>,
    // invariant: all values in id_map are valid keys in devices.
    id_map: HashMap<BindingId, C>,
    last_id: BindingId,
}

impl<C: IdMapCollectionKey, I> Default for Devices<C, I> {
    fn default() -> Self {
        Self { devices: IdMapCollection::new(), id_map: HashMap::new(), last_id: 0 }
    }
}

impl<C, I> Devices<C, I>
where
    C: IdMapCollectionKey + Clone + std::fmt::Debug,
{
    /// Allocates a new [`BindingId`].
    fn alloc_id(last_id: &mut BindingId) -> BindingId {
        *last_id += 1;
        *last_id
    }

    /// Adds a new device.
    ///
    /// Adds a new device if the informed `core_id` is valid (i.e., not
    /// currently tracked by [`Devices`]). A new [`BindingId`] will be allocated
    /// and a [`DeviceInfo`] struct will be created with the provided `info` and
    /// IDs.
    pub fn add_device<F: FnOnce(BindingId) -> I>(
        &mut self,
        core_id: C,
        info: F,
    ) -> Option<BindingId> {
        let Self { devices, id_map, last_id } = self;
        match devices.entry(core_id) {
            Entry::Occupied(_) => None,
            Entry::Vacant(entry) => {
                let id = Self::alloc_id(last_id);
                let core_id = entry.key().clone();
                assert_matches::assert_matches!(id_map.insert(id, core_id.clone()), None);
                let _: &mut DeviceInfo<_, _> =
                    entry.insert(DeviceInfo { id, core_id: core_id, info: info(id) });
                Some(id)
            }
        }
    }

    /// Removes a device from the internal list.
    ///
    /// Removes a device from the internal [`Devices`] list and returns the
    /// associated [`DeviceInfo`] if `id` is found or `None` otherwise.
    pub fn remove_device(&mut self, id: BindingId) -> Option<DeviceInfo<C, I>> {
        let Self { devices, id_map, last_id: _ } = self;
        id_map.remove(&id).and_then(|core_id| devices.remove(&core_id))
    }

    /// Gets an iterator over all tracked devices.
    #[cfg(test)]
    pub fn iter_devices(&self) -> impl Iterator<Item = &DeviceInfo<C, I>> {
        self.devices.iter()
    }

    /// Retrieve device with [`BindingId`].
    pub fn get_device(&self, id: BindingId) -> Option<&DeviceInfo<C, I>> {
        let Self { devices, id_map, last_id: _ } = self;
        id_map.get(&id).and_then(|device_id| devices.get(&device_id))
    }

    /// Retrieve mutable reference to device with [`BindingId`].
    pub fn get_device_mut(&mut self, id: BindingId) -> Option<&mut DeviceInfo<C, I>> {
        let Self { devices, id_map, last_id: _ } = self;
        id_map.get(&id).and_then(move |core_id| devices.get_mut(&core_id))
    }

    /// Retrieve associated `core_id` for [`BindingId`].
    pub fn get_core_id(&self, id: BindingId) -> Option<C> {
        self.id_map.get(&id).cloned()
    }

    /// Retrieve non-mutable reference to device by associated [`CoreId`] `id`.
    pub fn get_core_device(&self, id: C) -> Option<&DeviceInfo<C, I>> {
        self.devices.get(&id)
    }

    /// Retrieve mutable reference to device by associated [`CoreId`] `id`.
    pub fn get_core_device_mut(&mut self, id: C) -> Option<&mut DeviceInfo<C, I>> {
        self.devices.get_mut(&id)
    }

    /// Retrieve associated `binding_id` for `core_id`.
    pub fn get_binding_id(&self, core_id: C) -> Option<BindingId> {
        self.devices.get(&core_id).map(|d| d.id)
    }
}

/// Device specific iformation.
#[derive(Debug)]
pub enum DeviceSpecificInfo {
    Ethernet(EthernetInfo),
    Netdevice(NetdeviceInfo),
    Loopback(LoopbackInfo),
}

impl DeviceSpecificInfo {
    pub fn common_info(&self) -> &CommonInfo {
        match self {
            Self::Ethernet(i) => &i.common_info,
            Self::Netdevice(i) => &i.common_info,
            Self::Loopback(i) => &i.common_info,
        }
    }

    pub fn common_info_mut(&mut self) -> &mut CommonInfo {
        match self {
            Self::Ethernet(i) => &mut i.common_info,
            Self::Netdevice(i) => &mut i.common_info,
            Self::Loopback(i) => &mut i.common_info,
        }
    }
}

/// Information common to all devices.
#[derive(Debug)]
pub struct CommonInfo {
    pub mtu: u32,
    pub admin_enabled: bool,
    pub events: super::InterfaceEventProducer,
    pub name: String,
}

/// Loopback device information.
#[derive(Debug)]
pub struct LoopbackInfo {
    pub common_info: CommonInfo,
}

/// Ethernet device information.
#[derive(Debug)]
pub struct EthernetInfo {
    pub common_info: CommonInfo,
    pub client: eth::Client,
    pub mac: UnicastAddr<Mac>,
    pub features: Features,
    pub phy_up: bool,
}

impl From<EthernetInfo> for DeviceSpecificInfo {
    fn from(i: EthernetInfo) -> Self {
        Self::Ethernet(i)
    }
}

/// Network device information.
#[derive(Debug)]
pub struct NetdeviceInfo {
    pub common_info: CommonInfo,
    pub handler: super::netdevice_worker::PortHandler,
    pub mac: UnicastAddr<Mac>,
    pub phy_up: bool,
}

impl From<NetdeviceInfo> for DeviceSpecificInfo {
    fn from(i: NetdeviceInfo) -> Self {
        Self::Netdevice(i)
    }
}

/// Device information kept by [`Devices`].
#[derive(Debug, PartialEq)]
pub struct DeviceInfo<C = DeviceId, I = DeviceSpecificInfo> {
    id: BindingId,
    core_id: C,
    info: I,
}

impl<C, I> DeviceInfo<C, I>
where
    C: Clone,
{
    pub fn core_id(&self) -> C {
        self.core_id.clone()
    }

    pub fn info(&self) -> &I {
        &self.info
    }

    pub fn into_info(self) -> I {
        self.info
    }

    pub fn info_mut(&mut self) -> &mut I {
        &mut self.info
    }
}

#[cfg(test)]
mod tests {
    use assert_matches::assert_matches;
    use std::collections::HashSet;

    use super::*;

    type TestDevices = Devices<MockDeviceId, u64>;

    #[derive(Copy, Clone, Eq, PartialEq, Debug)]
    struct MockDeviceId(usize);

    impl IdMapCollectionKey for MockDeviceId {
        const VARIANT_COUNT: usize = 1;

        fn get_variant(&self) -> usize {
            0
        }

        fn get_id(&self) -> usize {
            self.0 as usize
        }
    }

    #[test]
    fn test_add_remove_device() {
        let mut d = TestDevices::default();
        let core_a = MockDeviceId(1);
        let core_b = MockDeviceId(2);
        let a = d.add_device(core_a, |id| id + 10).expect("can add device");
        let b = d.add_device(core_b, |id| id + 20).expect("can add device");
        assert_ne!(a, b, "allocated same id");
        assert_eq!(d.add_device(core_a, |id| id + 10), None, "can't add same id again");
        // check that ids are incrementing
        assert_eq!(d.last_id, 2);

        // check that devices are correctly inserted and carry the core id.
        assert_eq!(d.get_device(a).unwrap().core_id, core_a);
        assert_eq!(d.get_device(b).unwrap().core_id, core_b);
        assert_eq!(d.get_core_id(a).unwrap(), core_a);
        assert_eq!(d.get_core_id(b).unwrap(), core_b);
        assert_eq!(d.get_binding_id(core_a).unwrap(), a);
        assert_eq!(d.get_binding_id(core_b).unwrap(), b);

        // check that we can retrieve both devices by the core id:
        assert_matches!(d.get_core_device_mut(core_a), Some(_));
        assert_matches!(d.get_core_device_mut(core_b), Some(_));

        // remove both devices
        let info_a = d.remove_device(a).expect("can remove device");
        let info_b = d.remove_device(b).expect("can remove device");
        assert_eq!(info_a.info, a + 10);
        assert_eq!(info_b.info, b + 20);
        assert_eq!(info_a.core_id, core_a);
        assert_eq!(info_b.core_id, core_b);
        // removing device again will fail
        assert_eq!(d.remove_device(a), None);

        // retrieving the devices now should fail:
        assert_eq!(d.get_device(a), None);
        assert_eq!(d.get_core_id(a), None);
        assert_eq!(d.get_core_device_mut(core_a), None);

        assert!(d.devices.is_empty());
        assert!(d.id_map.is_empty());
    }

    #[test]
    fn test_iter() {
        let mut d = TestDevices::default();
        let core_a = MockDeviceId(1);
        let a = d.add_device(core_a, |id| id + 10).unwrap();
        assert_eq!(d.iter_devices().map(|d| d.id).collect::<HashSet<_>>(), HashSet::from([a]));

        let core_b = MockDeviceId(2);
        let b = d.add_device(core_b, |id| id + 20).unwrap();
        assert_eq!(d.iter_devices().map(|d| d.id).collect::<HashSet<_>>(), HashSet::from([a, b]));
    }
}
