use core::ffi::c_void;
use std::ffi::CStr;
use std::ffi::CString;
use std::ffi::OsStr;
use std::ffi::OsString;
use std::fmt::Debug;
use std::fs::remove_file;
use std::io;
use std::marker::PhantomData;
use std::mem;
use std::mem::transmute;
use std::ops::Deref;
use std::os::unix::ffi::OsStrExt;
use std::os::unix::io::AsFd;
use std::os::unix::io::AsRawFd;
use std::os::unix::io::BorrowedFd;
use std::os::unix::io::FromRawFd;
use std::os::unix::io::OwnedFd;
use std::os::unix::io::RawFd;
use std::path::Path;
use std::ptr;
use std::ptr::NonNull;
use std::slice;
use std::slice::from_raw_parts;

use bitflags::bitflags;
use libbpf_sys::bpf_map_info;
use libbpf_sys::bpf_obj_get_info_by_fd;

use crate::util;
use crate::util::parse_ret_i32;
use crate::util::validate_bpf_ret;
use crate::AsRawLibbpf;
use crate::Error;
use crate::ErrorExt as _;
use crate::Link;
use crate::Mut;
use crate::Result;

/// An immutable parsed but not yet loaded BPF map.
pub type OpenMap<'obj> = OpenMapImpl<'obj>;
/// A mutable parsed but not yet loaded BPF map.
pub type OpenMapMut<'obj> = OpenMapImpl<'obj, Mut>;


/// Represents a parsed but not yet loaded BPF map.
///
/// This object exposes operations that need to happen before the map is created.
///
/// Some methods require working with raw bytes. You may find libraries such as
/// [`plain`](https://crates.io/crates/plain) helpful.
#[derive(Debug)]
#[repr(transparent)]
pub struct OpenMapImpl<'obj, T = ()> {
    ptr: NonNull<libbpf_sys::bpf_map>,
    _phantom: PhantomData<&'obj T>,
}

// TODO: Document members.
#[allow(missing_docs)]
impl<'obj> OpenMap<'obj> {
    /// Create a new [`OpenMap`] from a ptr to a `libbpf_sys::bpf_map`.
    pub fn new(object: &'obj libbpf_sys::bpf_map) -> Self {
        // SAFETY: We inferred the address from a reference, which is always
        //         valid.
        Self {
            ptr: unsafe { NonNull::new_unchecked(object as *const _ as *mut _) },
            _phantom: PhantomData,
        }
    }

    /// Retrieve the [`OpenMap`]'s name.
    pub fn name(&self) -> &OsStr {
        // SAFETY: We ensured `ptr` is valid during construction.
        let name_ptr = unsafe { libbpf_sys::bpf_map__name(self.ptr.as_ptr()) };
        // SAFETY: `bpf_map__name` can return NULL but only if it's passed
        //          NULL. We know `ptr` is not NULL.
        let name_c_str = unsafe { CStr::from_ptr(name_ptr) };
        OsStr::from_bytes(name_c_str.to_bytes())
    }

    /// Retrieve type of the map.
    pub fn map_type(&self) -> MapType {
        let ty = unsafe { libbpf_sys::bpf_map__type(self.ptr.as_ptr()) };
        MapType::from(ty)
    }

    fn initial_value_raw(&self) -> (*mut u8, usize) {
        let mut size = 0u64;
        let ptr = unsafe {
            libbpf_sys::bpf_map__initial_value(self.ptr.as_ptr(), &mut size as *mut _ as _)
        };
        (ptr.cast(), size as _)
    }

    /// Retrieve the initial value of the map.
    pub fn initial_value(&self) -> Option<&[u8]> {
        let (ptr, size) = self.initial_value_raw();
        if ptr.is_null() {
            None
        } else {
            let data = unsafe { slice::from_raw_parts(ptr.cast::<u8>(), size) };
            Some(data)
        }
    }
}

impl<'obj> OpenMapMut<'obj> {
    /// Create a new [`OpenMapMut`] from a ptr to a `libbpf_sys::bpf_map`.
    pub fn new_mut(object: &'obj mut libbpf_sys::bpf_map) -> Self {
        Self {
            ptr: unsafe { NonNull::new_unchecked(object as *mut _) },
            _phantom: PhantomData,
        }
    }

    /// Retrieve the initial value of the map.
    pub fn initial_value_mut(&mut self) -> Option<&mut [u8]> {
        let (ptr, size) = self.initial_value_raw();
        if ptr.is_null() {
            None
        } else {
            let data = unsafe { slice::from_raw_parts_mut(ptr.cast::<u8>(), size) };
            Some(data)
        }
    }

    pub fn set_map_ifindex(&mut self, idx: u32) {
        unsafe { libbpf_sys::bpf_map__set_ifindex(self.ptr.as_ptr(), idx) };
    }

    pub fn set_initial_value(&mut self, data: &[u8]) -> Result<()> {
        let ret = unsafe {
            libbpf_sys::bpf_map__set_initial_value(
                self.ptr.as_ptr(),
                data.as_ptr() as *const c_void,
                data.len() as libbpf_sys::size_t,
            )
        };

        util::parse_ret(ret)
    }

    pub fn set_type(&mut self, ty: MapType) -> Result<()> {
        let ret = unsafe { libbpf_sys::bpf_map__set_type(self.ptr.as_ptr(), ty as u32) };
        util::parse_ret(ret)
    }

    pub fn set_key_size(&mut self, size: u32) -> Result<()> {
        let ret = unsafe { libbpf_sys::bpf_map__set_key_size(self.ptr.as_ptr(), size) };
        util::parse_ret(ret)
    }

    pub fn set_value_size(&mut self, size: u32) -> Result<()> {
        let ret = unsafe { libbpf_sys::bpf_map__set_value_size(self.ptr.as_ptr(), size) };
        util::parse_ret(ret)
    }

    pub fn set_max_entries(&mut self, count: u32) -> Result<()> {
        let ret = unsafe { libbpf_sys::bpf_map__set_max_entries(self.ptr.as_ptr(), count) };
        util::parse_ret(ret)
    }

    pub fn set_map_flags(&mut self, flags: u32) -> Result<()> {
        let ret = unsafe { libbpf_sys::bpf_map__set_map_flags(self.ptr.as_ptr(), flags) };
        util::parse_ret(ret)
    }

    pub fn set_numa_node(&mut self, numa_node: u32) -> Result<()> {
        let ret = unsafe { libbpf_sys::bpf_map__set_numa_node(self.ptr.as_ptr(), numa_node) };
        util::parse_ret(ret)
    }

    pub fn set_inner_map_fd(&mut self, inner_map_fd: BorrowedFd<'_>) -> Result<()> {
        let ret = unsafe {
            libbpf_sys::bpf_map__set_inner_map_fd(self.ptr.as_ptr(), inner_map_fd.as_raw_fd())
        };
        util::parse_ret(ret)
    }

    pub fn set_map_extra(&mut self, map_extra: u64) -> Result<()> {
        let ret = unsafe { libbpf_sys::bpf_map__set_map_extra(self.ptr.as_ptr(), map_extra) };
        util::parse_ret(ret)
    }

    pub fn set_autocreate(&mut self, autocreate: bool) -> Result<()> {
        let ret = unsafe { libbpf_sys::bpf_map__set_autocreate(self.ptr.as_ptr(), autocreate) };
        util::parse_ret(ret)
    }

    pub fn set_pin_path<P: AsRef<Path>>(&mut self, path: P) -> Result<()> {
        let path_c = util::path_to_cstring(path)?;
        let path_ptr = path_c.as_ptr();

        let ret = unsafe { libbpf_sys::bpf_map__set_pin_path(self.ptr.as_ptr(), path_ptr) };
        util::parse_ret(ret)
    }

    /// Reuse an fd for a BPF map
    pub fn reuse_fd(&mut self, fd: BorrowedFd<'_>) -> Result<()> {
        let ret = unsafe { libbpf_sys::bpf_map__reuse_fd(self.ptr.as_ptr(), fd.as_raw_fd()) };
        util::parse_ret(ret)
    }

    /// Reuse an already-pinned map for `self`.
    pub fn reuse_pinned_map<P: AsRef<Path>>(&mut self, path: P) -> Result<()> {
        let cstring = util::path_to_cstring(path)?;

        let fd = unsafe { libbpf_sys::bpf_obj_get(cstring.as_ptr()) };
        if fd < 0 {
            return Err(Error::from(io::Error::last_os_error()));
        }

        let fd = unsafe { OwnedFd::from_raw_fd(fd) };

        let reuse_result = self.reuse_fd(fd.as_fd());

        reuse_result
    }
}

impl<'obj> Deref for OpenMapMut<'obj> {
    type Target = OpenMap<'obj>;

    fn deref(&self) -> &Self::Target {
        // SAFETY: `OpenMapImpl` is `repr(transparent)` and so in-memory
        //         representation of both types is the same.
        unsafe { transmute::<&OpenMapMut<'obj>, &OpenMap<'obj>>(self) }
    }
}

impl<T> AsRawLibbpf for OpenMapImpl<'_, T> {
    type LibbpfType = libbpf_sys::bpf_map;

    /// Retrieve the underlying [`libbpf_sys::bpf_map`].
    fn as_libbpf_object(&self) -> NonNull<Self::LibbpfType> {
        self.ptr
    }
}

pub(crate) fn map_fd(map: NonNull<libbpf_sys::bpf_map>) -> Option<RawFd> {
    let fd = unsafe { libbpf_sys::bpf_map__fd(map.as_ptr()) };
    let fd = util::parse_ret_i32(fd).ok().map(|fd| fd as RawFd);
    fd
}

/// Return the size of one value including padding for interacting with per-cpu
/// maps. The values are aligned to 8 bytes.
fn percpu_aligned_value_size<M>(map: &M) -> usize
where
    M: MapCore + ?Sized,
{
    let val_size = map.value_size() as usize;
    util::roundup(val_size, 8)
}

/// Returns the size of the buffer needed for a lookup/update of a per-cpu map.
fn percpu_buffer_size<M>(map: &M) -> Result<usize>
where
    M: MapCore + ?Sized,
{
    let aligned_val_size = percpu_aligned_value_size(map);
    let ncpu = crate::num_possible_cpus()?;
    Ok(ncpu * aligned_val_size)
}

/// Apply a key check and return a null pointer in case of dealing with queue/stack/bloom-filter
/// map, before passing the key to the bpf functions that support the map of type
/// queue/stack/bloom-filter.
fn map_key<M>(map: &M, key: &[u8]) -> *const c_void
where
    M: MapCore + ?Sized,
{
    // For all they keyless maps we null out the key per documentation of libbpf
    if map.key_size() == 0 && map.map_type().is_keyless() {
        return ptr::null();
    }

    key.as_ptr() as *const c_void
}

/// Internal function to return a value from a map into a buffer of the given size.
fn lookup_raw<M>(map: &M, key: &[u8], flags: MapFlags, out_size: usize) -> Result<Option<Vec<u8>>>
where
    M: MapCore + ?Sized,
{
    if key.len() != map.key_size() as usize {
        return Err(Error::with_invalid_data(format!(
            "key_size {} != {}",
            key.len(),
            map.key_size()
        )));
    };

    let mut out: Vec<u8> = Vec::with_capacity(out_size);

    let ret = unsafe {
        libbpf_sys::bpf_map_lookup_elem_flags(
            map.as_fd().as_raw_fd(),
            map_key(map, key),
            out.as_mut_ptr() as *mut c_void,
            flags.bits(),
        )
    };

    if ret == 0 {
        unsafe {
            out.set_len(out_size);
        }
        Ok(Some(out))
    } else {
        let err = io::Error::last_os_error();
        if err.kind() == io::ErrorKind::NotFound {
            Ok(None)
        } else {
            Err(Error::from(err))
        }
    }
}

/// Internal function to update a map. This does not check the length of the
/// supplied value.
fn update_raw<M>(map: &M, key: &[u8], value: &[u8], flags: MapFlags) -> Result<()>
where
    M: MapCore + ?Sized,
{
    if key.len() != map.key_size() as usize {
        return Err(Error::with_invalid_data(format!(
            "key_size {} != {}",
            key.len(),
            map.key_size()
        )));
    };

    let ret = unsafe {
        libbpf_sys::bpf_map_update_elem(
            map.as_fd().as_raw_fd(),
            map_key(map, key),
            value.as_ptr() as *const c_void,
            flags.bits(),
        )
    };

    util::parse_ret(ret)
}

#[allow(clippy::wildcard_imports)]
mod private {
    use super::*;

    pub trait Sealed {}

    impl<T> Sealed for MapImpl<'_, T> {}
    impl Sealed for MapHandle {}
}

/// A trait representing core functionality common to fully initialized maps.
pub trait MapCore: Debug + AsFd + private::Sealed {
    /// Retrieve the map's name.
    fn name(&self) -> &OsStr;

    /// Retrieve type of the map.
    fn map_type(&self) -> MapType;

    /// Retrieve the size of the map's keys.
    fn key_size(&self) -> u32;

    /// Retrieve the size of the map's values.
    fn value_size(&self) -> u32;

    /// Fetch extra map information
    #[inline]
    fn info(&self) -> Result<MapInfo> {
        MapInfo::new(self.as_fd())
    }

    /// Returns an iterator over keys in this map
    ///
    /// Note that if the map is not stable (stable meaning no updates or deletes) during iteration,
    /// iteration can skip keys, restart from the beginning, or duplicate keys. In other words,
    /// iteration becomes unpredictable.
    fn keys(&self) -> MapKeyIter<'_> {
        MapKeyIter::new(self.as_fd(), self.key_size())
    }

    /// Returns map value as `Vec` of `u8`.
    ///
    /// `key` must have exactly [`Self::key_size()`] elements.
    ///
    /// If the map is one of the per-cpu data structures, the function [`Self::lookup_percpu()`]
    /// must be used.
    /// If the map is of type bloom_filter the function [`Self::lookup_bloom_filter()`] must be used
    fn lookup(&self, key: &[u8], flags: MapFlags) -> Result<Option<Vec<u8>>> {
        if self.map_type().is_bloom_filter() {
            return Err(Error::with_invalid_data(
                "lookup_bloom_filter() must be used for bloom filter maps",
            ));
        }
        if self.map_type().is_percpu() {
            return Err(Error::with_invalid_data(format!(
                "lookup_percpu() must be used for per-cpu maps (type of the map is {:?})",
                self.map_type(),
            )));
        }

        let out_size = self.value_size() as usize;
        lookup_raw(self, key, flags, out_size)
    }

    /// Returns if the given value is likely present in bloom_filter as `bool`.
    ///
    /// `value` must have exactly [`Self::value_size()`] elements.
    fn lookup_bloom_filter(&self, value: &[u8]) -> Result<bool> {
        let ret = unsafe {
            libbpf_sys::bpf_map_lookup_elem(
                self.as_fd().as_raw_fd(),
                ptr::null(),
                value.to_vec().as_mut_ptr() as *mut c_void,
            )
        };

        if ret == 0 {
            Ok(true)
        } else {
            let err = io::Error::last_os_error();
            if err.kind() == io::ErrorKind::NotFound {
                Ok(false)
            } else {
                Err(Error::from(err))
            }
        }
    }

    /// Returns one value per cpu as `Vec` of `Vec` of `u8` for per per-cpu maps.
    ///
    /// For normal maps, [`Self::lookup()`] must be used.
    fn lookup_percpu(&self, key: &[u8], flags: MapFlags) -> Result<Option<Vec<Vec<u8>>>> {
        if !self.map_type().is_percpu() && self.map_type() != MapType::Unknown {
            return Err(Error::with_invalid_data(format!(
                "lookup() must be used for maps that are not per-cpu (type of the map is {:?})",
                self.map_type(),
            )));
        }

        let val_size = self.value_size() as usize;
        let aligned_val_size = percpu_aligned_value_size(self);
        let out_size = percpu_buffer_size(self)?;

        let raw_res = lookup_raw(self, key, flags, out_size)?;
        if let Some(raw_vals) = raw_res {
            let mut out = Vec::new();
            for chunk in raw_vals.chunks_exact(aligned_val_size) {
                out.push(chunk[..val_size].to_vec());
            }
            Ok(Some(out))
        } else {
            Ok(None)
        }
    }

    /// Deletes an element from the map.
    ///
    /// `key` must have exactly [`Self::key_size()`] elements.
    fn delete(&self, key: &[u8]) -> Result<()> {
        if key.len() != self.key_size() as usize {
            return Err(Error::with_invalid_data(format!(
                "key_size {} != {}",
                key.len(),
                self.key_size()
            )));
        };

        let ret = unsafe {
            libbpf_sys::bpf_map_delete_elem(self.as_fd().as_raw_fd(), key.as_ptr() as *const c_void)
        };
        util::parse_ret(ret)
    }

    /// Deletes many elements in batch mode from the map.
    ///
    /// `keys` must have exactly [`Self::key_size()` * count] elements.
    fn delete_batch(
        &self,
        keys: &[u8],
        count: u32,
        elem_flags: MapFlags,
        flags: MapFlags,
    ) -> Result<()> {
        if keys.len() as u32 / count != self.key_size() || (keys.len() as u32) % count != 0 {
            return Err(Error::with_invalid_data(format!(
                "batch key_size {} != {} * {}",
                keys.len(),
                self.key_size(),
                count
            )));
        };

        #[allow(clippy::needless_update)]
        let opts = libbpf_sys::bpf_map_batch_opts {
            sz: mem::size_of::<libbpf_sys::bpf_map_batch_opts>() as _,
            elem_flags: elem_flags.bits(),
            flags: flags.bits(),
            // bpf_map_batch_opts might have padding fields on some platform
            ..Default::default()
        };

        let mut count = count;
        let ret = unsafe {
            libbpf_sys::bpf_map_delete_batch(
                self.as_fd().as_raw_fd(),
                keys.as_ptr() as *const c_void,
                (&mut count) as *mut u32,
                &opts as *const libbpf_sys::bpf_map_batch_opts,
            )
        };
        util::parse_ret(ret)
    }

    /// Same as [`Self::lookup()`] except this also deletes the key from the map.
    ///
    /// Note that this operation is currently only implemented in the kernel for [`MapType::Queue`]
    /// and [`MapType::Stack`].
    ///
    /// `key` must have exactly [`Self::key_size()`] elements.
    fn lookup_and_delete(&self, key: &[u8]) -> Result<Option<Vec<u8>>> {
        if key.len() != self.key_size() as usize {
            return Err(Error::with_invalid_data(format!(
                "key_size {} != {}",
                key.len(),
                self.key_size()
            )));
        };

        let mut out: Vec<u8> = Vec::with_capacity(self.value_size() as usize);

        let ret = unsafe {
            libbpf_sys::bpf_map_lookup_and_delete_elem(
                self.as_fd().as_raw_fd(),
                map_key(self, key),
                out.as_mut_ptr() as *mut c_void,
            )
        };

        if ret == 0 {
            unsafe {
                out.set_len(self.value_size() as usize);
            }
            Ok(Some(out))
        } else {
            let err = io::Error::last_os_error();
            if err.kind() == io::ErrorKind::NotFound {
                Ok(None)
            } else {
                Err(Error::from(err))
            }
        }
    }

    /// Update an element.
    ///
    /// `key` must have exactly [`Self::key_size()`] elements. `value` must have exactly
    /// [`Self::value_size()`] elements.
    ///
    /// For per-cpu maps, [`Self::update_percpu()`] must be used.
    fn update(&self, key: &[u8], value: &[u8], flags: MapFlags) -> Result<()> {
        if self.map_type().is_percpu() {
            return Err(Error::with_invalid_data(format!(
                "update_percpu() must be used for per-cpu maps (type of the map is {:?})",
                self.map_type(),
            )));
        }

        if value.len() != self.value_size() as usize {
            return Err(Error::with_invalid_data(format!(
                "value_size {} != {}",
                value.len(),
                self.value_size()
            )));
        };

        update_raw(self, key, value, flags)
    }

    /// Updates many elements in batch mode in the map
    ///
    /// `keys` must have exactly [`Self::key_size()` * count] elements. `value` must have exactly
    /// [`Self::key_size()` * count] elements
    fn update_batch(
        &self,
        keys: &[u8],
        values: &[u8],
        count: u32,
        elem_flags: MapFlags,
        flags: MapFlags,
    ) -> Result<()> {
        if keys.len() as u32 / count != self.key_size() || (keys.len() as u32) % count != 0 {
            return Err(Error::with_invalid_data(format!(
                "batch key_size {} != {} * {}",
                keys.len(),
                self.key_size(),
                count
            )));
        };

        if values.len() as u32 / count != self.value_size() || (values.len() as u32) % count != 0 {
            return Err(Error::with_invalid_data(format!(
                "batch value_size {} != {} * {}",
                values.len(),
                self.value_size(),
                count
            )));
        }

        #[allow(clippy::needless_update)]
        let opts = libbpf_sys::bpf_map_batch_opts {
            sz: mem::size_of::<libbpf_sys::bpf_map_batch_opts>() as _,
            elem_flags: elem_flags.bits(),
            flags: flags.bits(),
            // bpf_map_batch_opts might have padding fields on some platform
            ..Default::default()
        };

        let mut count = count;
        let ret = unsafe {
            libbpf_sys::bpf_map_update_batch(
                self.as_fd().as_raw_fd(),
                keys.as_ptr() as *const c_void,
                values.as_ptr() as *const c_void,
                (&mut count) as *mut u32,
                &opts as *const libbpf_sys::bpf_map_batch_opts,
            )
        };

        util::parse_ret(ret)
    }

    /// Update an element in an per-cpu map with one value per cpu.
    ///
    /// `key` must have exactly [`Self::key_size()`] elements. `value` must have one
    /// element per cpu (see [`num_possible_cpus`][crate::num_possible_cpus])
    /// with exactly [`Self::value_size()`] elements each.
    ///
    /// For per-cpu maps, [`Self::update_percpu()`] must be used.
    fn update_percpu(&self, key: &[u8], values: &[Vec<u8>], flags: MapFlags) -> Result<()> {
        if !self.map_type().is_percpu() && self.map_type() != MapType::Unknown {
            return Err(Error::with_invalid_data(format!(
                "update() must be used for maps that are not per-cpu (type of the map is {:?})",
                self.map_type(),
            )));
        }

        if values.len() != crate::num_possible_cpus()? {
            return Err(Error::with_invalid_data(format!(
                "number of values {} != number of cpus {}",
                values.len(),
                crate::num_possible_cpus()?
            )));
        };

        let val_size = self.value_size() as usize;
        let aligned_val_size = percpu_aligned_value_size(self);
        let buf_size = percpu_buffer_size(self)?;

        let mut value_buf = vec![0; buf_size];

        for (i, val) in values.iter().enumerate() {
            if val.len() != val_size {
                return Err(Error::with_invalid_data(format!(
                    "value size for cpu {} is {} != {}",
                    i,
                    val.len(),
                    val_size
                )));
            }

            value_buf[(i * aligned_val_size)..(i * aligned_val_size + val_size)]
                .copy_from_slice(val);
        }

        update_raw(self, key, &value_buf, flags)
    }
}

/// An immutable loaded BPF map.
pub type Map<'obj> = MapImpl<'obj>;
/// A mutable loaded BPF map.
pub type MapMut<'obj> = MapImpl<'obj, Mut>;

/// Represents a libbpf-created map.
///
/// Some methods require working with raw bytes. You may find libraries such as
/// [`plain`](https://crates.io/crates/plain) helpful.
#[derive(Debug)]
pub struct MapImpl<'obj, T = ()> {
    ptr: NonNull<libbpf_sys::bpf_map>,
    _phantom: PhantomData<&'obj T>,
}

impl<'obj> Map<'obj> {
    /// Create a [`Map`] from a [`libbpf_sys::bpf_map`].
    pub fn new(map: &'obj libbpf_sys::bpf_map) -> Self {
        // SAFETY: We inferred the address from a reference, which is always
        //         valid.
        let ptr = unsafe { NonNull::new_unchecked(map as *const _ as *mut _) };
        assert!(
            map_fd(ptr).is_some(),
            "provided BPF map does not have file descriptor"
        );

        Self {
            ptr,
            _phantom: PhantomData,
        }
    }

    /// Create a [`Map`] from a [`libbpf_sys::bpf_map`] that does not contain a
    /// file descriptor.
    ///
    /// The caller has to ensure that the [`AsFd`] impl is not used, or a panic
    /// will be the result.
    ///
    /// # Safety
    ///
    /// The pointer must point to a loaded map.
    #[doc(hidden)]
    pub unsafe fn from_map_without_fd(ptr: NonNull<libbpf_sys::bpf_map>) -> Self {
        Self {
            ptr,
            _phantom: PhantomData,
        }
    }

    /// Returns whether map is pinned or not flag
    pub fn is_pinned(&self) -> bool {
        unsafe { libbpf_sys::bpf_map__is_pinned(self.ptr.as_ptr()) }
    }

    /// Returns the pin_path if the map is pinned, otherwise, None is returned
    pub fn get_pin_path(&self) -> Option<&OsStr> {
        let path_ptr = unsafe { libbpf_sys::bpf_map__pin_path(self.ptr.as_ptr()) };
        if path_ptr.is_null() {
            // means map is not pinned
            return None;
        }
        let path_c_str = unsafe { CStr::from_ptr(path_ptr) };
        Some(OsStr::from_bytes(path_c_str.to_bytes()))
    }
}

impl<'obj> MapMut<'obj> {
    /// Create a [`MapMut`] from a [`libbpf_sys::bpf_map`].
    pub fn new_mut(map: &'obj mut libbpf_sys::bpf_map) -> Self {
        // SAFETY: We inferred the address from a reference, which is always
        //         valid.
        let ptr = unsafe { NonNull::new_unchecked(map as *mut _) };
        assert!(
            map_fd(ptr).is_some(),
            "provided BPF map does not have file descriptor"
        );

        Self {
            ptr,
            _phantom: PhantomData,
        }
    }

    /// [Pin](https://facebookmicrosites.github.io/bpf/blog/2018/08/31/object-lifetime.html#bpffs)
    /// this map to bpffs.
    pub fn pin<P: AsRef<Path>>(&mut self, path: P) -> Result<()> {
        let path_c = util::path_to_cstring(path)?;
        let path_ptr = path_c.as_ptr();

        let ret = unsafe { libbpf_sys::bpf_map__pin(self.ptr.as_ptr(), path_ptr) };
        util::parse_ret(ret)
    }

    /// [Unpin](https://facebookmicrosites.github.io/bpf/blog/2018/08/31/object-lifetime.html#bpffs)
    /// this map from bpffs.
    pub fn unpin<P: AsRef<Path>>(&mut self, path: P) -> Result<()> {
        let path_c = util::path_to_cstring(path)?;
        let path_ptr = path_c.as_ptr();
        let ret = unsafe { libbpf_sys::bpf_map__unpin(self.ptr.as_ptr(), path_ptr) };
        util::parse_ret(ret)
    }

    /// Attach a struct ops map
    pub fn attach_struct_ops(&mut self) -> Result<Link> {
        if self.map_type() != MapType::StructOps {
            return Err(Error::with_invalid_data(format!(
                "Invalid map type ({:?}) for attach_struct_ops()",
                self.map_type(),
            )));
        }

        let ptr = unsafe { libbpf_sys::bpf_map__attach_struct_ops(self.ptr.as_ptr()) };
        let ptr = validate_bpf_ret(ptr).context("failed to attach struct_ops")?;
        // SAFETY: the pointer came from libbpf and has been checked for errors.
        let link = unsafe { Link::new(ptr) };
        Ok(link)
    }
}

impl<'obj> Deref for MapMut<'obj> {
    type Target = Map<'obj>;

    fn deref(&self) -> &Self::Target {
        unsafe { transmute::<&MapMut<'obj>, &Map<'obj>>(self) }
    }
}

impl<T> AsFd for MapImpl<'_, T> {
    #[inline]
    fn as_fd(&self) -> BorrowedFd<'_> {
        // SANITY: Our map must always have a file descriptor associated with
        //         it.
        let fd = map_fd(self.ptr).unwrap();
        // SAFETY: `fd` is guaranteed to be valid for the lifetime of
        //         the created object.
        let fd = unsafe { BorrowedFd::borrow_raw(fd as _) };
        fd
    }
}

impl<T> MapCore for MapImpl<'_, T>
where
    T: Debug,
{
    fn name(&self) -> &OsStr {
        // SAFETY: We ensured `ptr` is valid during construction.
        let name_ptr = unsafe { libbpf_sys::bpf_map__name(self.ptr.as_ptr()) };
        // SAFETY: `bpf_map__name` can return NULL but only if it's passed
        //          NULL. We know `ptr` is not NULL.
        let name_c_str = unsafe { CStr::from_ptr(name_ptr) };
        OsStr::from_bytes(name_c_str.to_bytes())
    }

    #[inline]
    fn map_type(&self) -> MapType {
        let ty = unsafe { libbpf_sys::bpf_map__type(self.ptr.as_ptr()) };
        MapType::from(ty)
    }

    #[inline]
    fn key_size(&self) -> u32 {
        unsafe { libbpf_sys::bpf_map__key_size(self.ptr.as_ptr()) }
    }

    #[inline]
    fn value_size(&self) -> u32 {
        unsafe { libbpf_sys::bpf_map__value_size(self.ptr.as_ptr()) }
    }
}

impl AsRawLibbpf for Map<'_> {
    type LibbpfType = libbpf_sys::bpf_map;

    /// Retrieve the underlying [`libbpf_sys::bpf_map`].
    #[inline]
    fn as_libbpf_object(&self) -> NonNull<Self::LibbpfType> {
        self.ptr
    }
}

/// A handle to a map. Handles can be duplicated and dropped.
///
/// While possible to [created directly][MapHandle::create], in many cases it is
/// useful to create such a handle from an existing [`Map`]:
/// ```no_run
/// # use libbpf_rs::Map;
/// # use libbpf_rs::MapHandle;
/// # let get_map = || -> &Map { todo!() };
/// let map: &Map = get_map();
/// let map_handle = MapHandle::try_from(map).unwrap();
/// ```
///
/// Some methods require working with raw bytes. You may find libraries such as
/// [`plain`](https://crates.io/crates/plain) helpful.
#[derive(Debug)]
pub struct MapHandle {
    fd: OwnedFd,
    name: OsString,
    ty: MapType,
    key_size: u32,
    value_size: u32,
}

impl MapHandle {
    /// Create a bpf map whose data is not managed by libbpf.
    pub fn create<T: AsRef<OsStr>>(
        map_type: MapType,
        name: Option<T>,
        key_size: u32,
        value_size: u32,
        max_entries: u32,
        opts: &libbpf_sys::bpf_map_create_opts,
    ) -> Result<Self> {
        let name = match name {
            Some(name) => name.as_ref().to_os_string(),
            // The old version kernel don't support specifying map name.
            None => OsString::new(),
        };
        let name_c_str = CString::new(name.as_bytes()).map_err(|_| {
            Error::with_invalid_data(format!("invalid name `{name:?}`: has NUL bytes"))
        })?;
        let name_c_ptr = if name.is_empty() {
            ptr::null()
        } else {
            name_c_str.as_bytes_with_nul().as_ptr()
        };

        let fd = unsafe {
            libbpf_sys::bpf_map_create(
                map_type.into(),
                name_c_ptr.cast(),
                key_size,
                value_size,
                max_entries,
                opts,
            )
        };
        let () = util::parse_ret(fd)?;

        Ok(Self {
            // SAFETY: A file descriptor coming from the `bpf_map_create`
            //         function is always suitable for ownership and can be
            //         cleaned up with close.
            fd: unsafe { OwnedFd::from_raw_fd(fd) },
            name,
            ty: map_type,
            key_size,
            value_size,
        })
    }

    /// Open a previously pinned map from its path.
    ///
    /// # Panics
    /// If the path contains null bytes.
    pub fn from_pinned_path<P: AsRef<Path>>(path: P) -> Result<Self> {
        fn inner(path: &Path) -> Result<MapHandle> {
            let p = CString::new(path.as_os_str().as_bytes()).expect("path contained null bytes");
            let fd = parse_ret_i32(unsafe {
                // SAFETY
                // p is never null since we allocated ourselves.
                libbpf_sys::bpf_obj_get(p.as_ptr())
            })?;
            MapHandle::from_fd(unsafe {
                // SAFETY
                // A file descriptor coming from the bpf_obj_get function is always suitable for
                // ownership and can be cleaned up with close.
                OwnedFd::from_raw_fd(fd)
            })
        }

        inner(path.as_ref())
    }

    /// Open a loaded map from its map id.
    pub fn from_map_id(id: u32) -> Result<Self> {
        parse_ret_i32(unsafe {
            // SAFETY
            // This function is always safe to call.
            libbpf_sys::bpf_map_get_fd_by_id(id)
        })
        .map(|fd| unsafe {
            // SAFETY
            // A file descriptor coming from the bpf_map_get_fd_by_id function is always suitable
            // for ownership and can be cleaned up with close.
            OwnedFd::from_raw_fd(fd)
        })
        .and_then(Self::from_fd)
    }

    fn from_fd(fd: OwnedFd) -> Result<Self> {
        let info = MapInfo::new(fd.as_fd())?;
        Ok(Self {
            fd,
            name: info.name()?.into(),
            ty: info.map_type(),
            key_size: info.info.key_size,
            value_size: info.info.value_size,
        })
    }

    /// Freeze the map as read-only from user space.
    ///
    /// Entries from a frozen map can no longer be updated or deleted with the
    /// bpf() system call. This operation is not reversible, and the map remains
    /// immutable from user space until its destruction. However, read and write
    /// permissions for BPF programs to the map remain unchanged.
    pub fn freeze(&self) -> Result<()> {
        let ret = unsafe { libbpf_sys::bpf_map_freeze(self.fd.as_raw_fd()) };

        util::parse_ret(ret)
    }

    /// [Pin](https://facebookmicrosites.github.io/bpf/blog/2018/08/31/object-lifetime.html#bpffs)
    /// this map to bpffs.
    pub fn pin<P: AsRef<Path>>(&mut self, path: P) -> Result<()> {
        let path_c = util::path_to_cstring(path)?;
        let path_ptr = path_c.as_ptr();

        let ret = unsafe { libbpf_sys::bpf_obj_pin(self.fd.as_raw_fd(), path_ptr) };
        util::parse_ret(ret)
    }

    /// [Unpin](https://facebookmicrosites.github.io/bpf/blog/2018/08/31/object-lifetime.html#bpffs)
    /// this map from bpffs.
    pub fn unpin<P: AsRef<Path>>(&mut self, path: P) -> Result<()> {
        remove_file(path).context("failed to remove pin map")
    }
}

impl MapCore for MapHandle {
    #[inline]
    fn name(&self) -> &OsStr {
        &self.name
    }

    #[inline]
    fn map_type(&self) -> MapType {
        self.ty
    }

    #[inline]
    fn key_size(&self) -> u32 {
        self.key_size
    }

    #[inline]
    fn value_size(&self) -> u32 {
        self.value_size
    }
}

impl AsFd for MapHandle {
    #[inline]
    fn as_fd(&self) -> BorrowedFd<'_> {
        self.fd.as_fd()
    }
}

impl<T> TryFrom<&MapImpl<'_, T>> for MapHandle
where
    T: Debug,
{
    type Error = Error;

    fn try_from(other: &MapImpl<'_, T>) -> Result<Self> {
        Ok(Self {
            fd: other
                .as_fd()
                .try_clone_to_owned()
                .context("failed to duplicate map file descriptor")?,
            name: other.name().to_os_string(),
            ty: other.map_type(),
            key_size: other.key_size(),
            value_size: other.value_size(),
        })
    }
}

impl TryFrom<&MapHandle> for MapHandle {
    type Error = Error;

    fn try_from(other: &MapHandle) -> Result<Self> {
        Ok(Self {
            fd: other
                .as_fd()
                .try_clone_to_owned()
                .context("failed to duplicate map file descriptor")?,
            name: other.name().to_os_string(),
            ty: other.map_type(),
            key_size: other.key_size(),
            value_size: other.value_size(),
        })
    }
}

bitflags! {
    /// Flags to configure [`Map`] operations.
    #[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Clone, Copy)]
    pub struct MapFlags: u64 {
        /// See [`libbpf_sys::BPF_ANY`].
        const ANY      = libbpf_sys::BPF_ANY as _;
        /// See [`libbpf_sys::BPF_NOEXIST`].
        const NO_EXIST = libbpf_sys::BPF_NOEXIST as _;
        /// See [`libbpf_sys::BPF_EXIST`].
        const EXIST    = libbpf_sys::BPF_EXIST as _;
        /// See [`libbpf_sys::BPF_F_LOCK`].
        const LOCK     = libbpf_sys::BPF_F_LOCK as _;
    }
}

/// Type of a [`Map`]. Maps to `enum bpf_map_type` in kernel uapi.
// If you add a new per-cpu map, also update `is_percpu`.
#[non_exhaustive]
#[repr(u32)]
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
// TODO: Document members.
#[allow(missing_docs)]
pub enum MapType {
    Unspec = 0,
    Hash,
    Array,
    ProgArray,
    PerfEventArray,
    PercpuHash,
    PercpuArray,
    StackTrace,
    CgroupArray,
    LruHash,
    LruPercpuHash,
    LpmTrie,
    ArrayOfMaps,
    HashOfMaps,
    Devmap,
    Sockmap,
    Cpumap,
    Xskmap,
    Sockhash,
    CgroupStorage,
    ReuseportSockarray,
    PercpuCgroupStorage,
    Queue,
    Stack,
    SkStorage,
    DevmapHash,
    StructOps,
    RingBuf,
    InodeStorage,
    TaskStorage,
    BloomFilter,
    UserRingBuf,
    /// We choose to specify our own "unknown" type here b/c it's really up to the kernel
    /// to decide if it wants to reject the map. If it accepts it, it just means whoever
    /// using this library is a bit out of date.
    Unknown = u32::MAX,
}

impl MapType {
    /// Returns if the map is of one of the per-cpu types.
    pub fn is_percpu(&self) -> bool {
        matches!(
            self,
            MapType::PercpuArray
                | MapType::PercpuHash
                | MapType::LruPercpuHash
                | MapType::PercpuCgroupStorage
        )
    }

    /// Returns if the map is keyless map type as per documentation of libbpf
    /// Keyless map types are: Queues, Stacks and Bloom Filters
    fn is_keyless(&self) -> bool {
        matches!(self, MapType::Queue | MapType::Stack | MapType::BloomFilter)
    }

    /// Returns if the map is of bloom filter type
    pub fn is_bloom_filter(&self) -> bool {
        MapType::BloomFilter.eq(self)
    }

    /// Detects if host kernel supports this BPF map type.
    ///
    /// Make sure the process has required set of CAP_* permissions (or runs as
    /// root) when performing feature checking.
    pub fn is_supported(&self) -> Result<bool> {
        let ret = unsafe { libbpf_sys::libbpf_probe_bpf_map_type(*self as u32, ptr::null()) };
        match ret {
            0 => Ok(false),
            1 => Ok(true),
            _ => Err(Error::from_raw_os_error(-ret)),
        }
    }
}

impl From<u32> for MapType {
    fn from(value: u32) -> Self {
        use MapType::*;

        match value {
            x if x == Unspec as u32 => Unspec,
            x if x == Hash as u32 => Hash,
            x if x == Array as u32 => Array,
            x if x == ProgArray as u32 => ProgArray,
            x if x == PerfEventArray as u32 => PerfEventArray,
            x if x == PercpuHash as u32 => PercpuHash,
            x if x == PercpuArray as u32 => PercpuArray,
            x if x == StackTrace as u32 => StackTrace,
            x if x == CgroupArray as u32 => CgroupArray,
            x if x == LruHash as u32 => LruHash,
            x if x == LruPercpuHash as u32 => LruPercpuHash,
            x if x == LpmTrie as u32 => LpmTrie,
            x if x == ArrayOfMaps as u32 => ArrayOfMaps,
            x if x == HashOfMaps as u32 => HashOfMaps,
            x if x == Devmap as u32 => Devmap,
            x if x == Sockmap as u32 => Sockmap,
            x if x == Cpumap as u32 => Cpumap,
            x if x == Xskmap as u32 => Xskmap,
            x if x == Sockhash as u32 => Sockhash,
            x if x == CgroupStorage as u32 => CgroupStorage,
            x if x == ReuseportSockarray as u32 => ReuseportSockarray,
            x if x == PercpuCgroupStorage as u32 => PercpuCgroupStorage,
            x if x == Queue as u32 => Queue,
            x if x == Stack as u32 => Stack,
            x if x == SkStorage as u32 => SkStorage,
            x if x == DevmapHash as u32 => DevmapHash,
            x if x == StructOps as u32 => StructOps,
            x if x == RingBuf as u32 => RingBuf,
            x if x == InodeStorage as u32 => InodeStorage,
            x if x == TaskStorage as u32 => TaskStorage,
            x if x == BloomFilter as u32 => BloomFilter,
            x if x == UserRingBuf as u32 => UserRingBuf,
            _ => Unknown,
        }
    }
}

impl From<MapType> for u32 {
    fn from(value: MapType) -> Self {
        value as u32
    }
}

/// An iterator over the keys of a BPF map.
#[derive(Debug)]
pub struct MapKeyIter<'map> {
    map_fd: BorrowedFd<'map>,
    prev: Option<Vec<u8>>,
    next: Vec<u8>,
}

impl<'map> MapKeyIter<'map> {
    fn new(map_fd: BorrowedFd<'map>, key_size: u32) -> Self {
        Self {
            map_fd,
            prev: None,
            next: vec![0; key_size as usize],
        }
    }
}

impl Iterator for MapKeyIter<'_> {
    type Item = Vec<u8>;

    fn next(&mut self) -> Option<Self::Item> {
        let prev = self.prev.as_ref().map_or(ptr::null(), |p| p.as_ptr());

        let ret = unsafe {
            libbpf_sys::bpf_map_get_next_key(
                self.map_fd.as_raw_fd(),
                prev as _,
                self.next.as_mut_ptr() as _,
            )
        };
        if ret != 0 {
            None
        } else {
            self.prev = Some(self.next.clone());
            Some(self.next.clone())
        }
    }
}

/// A convenience wrapper for [`bpf_map_info`][libbpf_sys::bpf_map_info]. It
/// provides the ability to retrieve the details of a certain map.
#[derive(Debug)]
pub struct MapInfo {
    /// The inner [`bpf_map_info`][libbpf_sys::bpf_map_info] object.
    pub info: bpf_map_info,
}

impl MapInfo {
    /// Create a `MapInfo` object from a fd.
    pub fn new(fd: BorrowedFd<'_>) -> Result<Self> {
        let mut map_info = bpf_map_info::default();
        let mut size = mem::size_of_val(&map_info) as u32;
        // SAFETY: All pointers are derived from references and hence valid.
        let () = util::parse_ret(unsafe {
            bpf_obj_get_info_by_fd(
                fd.as_raw_fd(),
                &mut map_info as *mut bpf_map_info as *mut c_void,
                &mut size as *mut u32,
            )
        })?;
        Ok(Self { info: map_info })
    }

    /// Get the map type
    #[inline]
    pub fn map_type(&self) -> MapType {
        MapType::from(self.info.type_)
    }

    /// Get the name of this map.
    ///
    /// Returns error if the underlying data in the structure is not a valid
    /// utf-8 string.
    pub fn name<'a>(&self) -> Result<&'a str> {
        // SAFETY: convert &[i8] to &[u8], and then cast that to &str. i8 and u8 has the same size.
        let char_slice =
            unsafe { from_raw_parts(self.info.name[..].as_ptr().cast(), self.info.name.len()) };

        util::c_char_slice_to_cstr(char_slice)
            .ok_or_else(|| Error::with_invalid_data("no nul byte found"))?
            .to_str()
            .map_err(Error::with_invalid_data)
    }

    /// Get the map flags.
    #[inline]
    pub fn flags(&self) -> MapFlags {
        MapFlags::from_bits_truncate(self.info.map_flags as u64)
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    use std::mem::discriminant;

    #[test]
    fn map_type() {
        use MapType::*;

        for t in [
            Unspec,
            Hash,
            Array,
            ProgArray,
            PerfEventArray,
            PercpuHash,
            PercpuArray,
            StackTrace,
            CgroupArray,
            LruHash,
            LruPercpuHash,
            LpmTrie,
            ArrayOfMaps,
            HashOfMaps,
            Devmap,
            Sockmap,
            Cpumap,
            Xskmap,
            Sockhash,
            CgroupStorage,
            ReuseportSockarray,
            PercpuCgroupStorage,
            Queue,
            Stack,
            SkStorage,
            DevmapHash,
            StructOps,
            RingBuf,
            InodeStorage,
            TaskStorage,
            BloomFilter,
            UserRingBuf,
            Unknown,
        ] {
            // check if discriminants match after a roundtrip conversion
            assert_eq!(discriminant(&t), discriminant(&MapType::from(t as u32)));
        }
    }
}
