// `rustdoc` is buggy, claiming that we have some links to private items
// when they are actually public.
#![allow(rustdoc::private_intra_doc_links)]

use std::ffi::c_void;
use std::ffi::CStr;
use std::ffi::OsStr;
use std::marker::PhantomData;
use std::mem;
use std::mem::size_of;
use std::mem::size_of_val;
use std::mem::transmute;
use std::ops::Deref;
use std::os::unix::ffi::OsStrExt as _;
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::path::Path;
use std::ptr;
use std::ptr::NonNull;
use std::slice;

use libbpf_sys::bpf_func_id;

use crate::util;
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;

/// Options to optionally be provided when attaching to a uprobe.
#[derive(Clone, Debug, Default)]
pub struct UprobeOpts {
    /// Offset of kernel reference counted USDT semaphore.
    pub ref_ctr_offset: usize,
    /// Custom user-provided value accessible through `bpf_get_attach_cookie`.
    pub cookie: u64,
    /// uprobe is return probe, invoked at function return time.
    pub retprobe: bool,
    /// Function name to attach to.
    ///
    /// Could be an unqualified ("abc") or library-qualified "abc@LIBXYZ" name.
    /// To specify function entry, `func_name` should be set while `func_offset`
    /// argument to should be 0. To trace an offset within a function, specify
    /// `func_name` and use `func_offset` argument to specify offset within the
    /// function. Shared library functions must specify the shared library
    /// binary_path.
    pub func_name: String,
    #[doc(hidden)]
    pub _non_exhaustive: (),
}

/// Options to optionally be provided when attaching to a USDT.
#[derive(Clone, Debug, Default)]
pub struct UsdtOpts {
    /// Custom user-provided value accessible through `bpf_usdt_cookie`.
    pub cookie: u64,
    #[doc(hidden)]
    pub _non_exhaustive: (),
}

impl From<UsdtOpts> for libbpf_sys::bpf_usdt_opts {
    fn from(opts: UsdtOpts) -> Self {
        let UsdtOpts {
            cookie,
            _non_exhaustive,
        } = opts;
        #[allow(clippy::needless_update)]
        libbpf_sys::bpf_usdt_opts {
            sz: size_of::<Self>() as _,
            usdt_cookie: cookie,
            // bpf_usdt_opts might have padding fields on some platform
            ..Default::default()
        }
    }
}

/// Options to optionally be provided when attaching to a tracepoint.
#[derive(Clone, Debug, Default)]
pub struct TracepointOpts {
    /// Custom user-provided value accessible through `bpf_get_attach_cookie`.
    pub cookie: u64,
    #[doc(hidden)]
    pub _non_exhaustive: (),
}

impl From<TracepointOpts> for libbpf_sys::bpf_tracepoint_opts {
    fn from(opts: TracepointOpts) -> Self {
        let TracepointOpts {
            cookie,
            _non_exhaustive,
        } = opts;

        #[allow(clippy::needless_update)]
        libbpf_sys::bpf_tracepoint_opts {
            sz: size_of::<Self>() as _,
            bpf_cookie: cookie,
            // bpf_tracepoint_opts might have padding fields on some platform
            ..Default::default()
        }
    }
}


/// An immutable parsed but not yet loaded BPF program.
pub type OpenProgram<'obj> = OpenProgramImpl<'obj>;
/// A mutable parsed but not yet loaded BPF program.
pub type OpenProgramMut<'obj> = OpenProgramImpl<'obj, Mut>;

/// Represents a parsed but not yet loaded BPF program.
///
/// This object exposes operations that need to happen before the program is loaded.
#[derive(Debug)]
#[repr(transparent)]
pub struct OpenProgramImpl<'obj, T = ()> {
    ptr: NonNull<libbpf_sys::bpf_program>,
    _phantom: PhantomData<&'obj T>,
}

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

    // The `ProgramType` of this `OpenProgram`.
    pub fn prog_type(&self) -> ProgramType {
        ProgramType::from(unsafe { libbpf_sys::bpf_program__type(self.ptr.as_ptr()) })
    }

    /// Retrieve the name of this `OpenProgram`.
    pub fn name(&self) -> &OsStr {
        let name_ptr = unsafe { libbpf_sys::bpf_program__name(self.ptr.as_ptr()) };
        let name_c_str = unsafe { CStr::from_ptr(name_ptr) };
        // SAFETY: `bpf_program__name` always returns a non-NULL pointer.
        OsStr::from_bytes(name_c_str.to_bytes())
    }

    /// Retrieve the name of the section this `OpenProgram` belongs to.
    pub fn section(&self) -> &OsStr {
        // SAFETY: The program is always valid.
        let p = unsafe { libbpf_sys::bpf_program__section_name(self.ptr.as_ptr()) };
        // SAFETY: `bpf_program__section_name` will always return a non-NULL
        //         pointer.
        let section_c_str = unsafe { CStr::from_ptr(p) };
        let section = OsStr::from_bytes(section_c_str.to_bytes());
        section
    }

    /// Returns the number of instructions that form the program.
    ///
    /// Note: Keep in mind, libbpf can modify the program's instructions
    /// and consequently its instruction count, as it processes the BPF object file.
    /// So [`OpenProgram::insn_cnt`] and [`Program::insn_cnt`] may return different values.
    pub fn insn_cnt(&self) -> usize {
        unsafe { libbpf_sys::bpf_program__insn_cnt(self.ptr.as_ptr()) as usize }
    }

    /// Gives read-only access to BPF program's underlying BPF instructions.
    ///
    /// Keep in mind, libbpf can modify and append/delete BPF program's
    /// instructions as it processes BPF object file and prepares everything for
    /// uploading into the kernel. So [`OpenProgram::insns`] and [`Program::insns`] may return
    /// different sets of instructions. As an example, during BPF object load phase BPF program
    /// instructions will be CO-RE-relocated, BPF subprograms instructions will be appended, ldimm64
    /// instructions will have FDs embedded, etc. So instructions returned before load and after it
    /// might be quite different.
    pub fn insns(&self) -> &[libbpf_sys::bpf_insn] {
        let count = self.insn_cnt();
        let ptr = unsafe { libbpf_sys::bpf_program__insns(self.ptr.as_ptr()) };
        unsafe { slice::from_raw_parts(ptr, count) }
    }
}

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

    pub fn set_prog_type(&mut self, prog_type: ProgramType) {
        let rc = unsafe { libbpf_sys::bpf_program__set_type(self.ptr.as_ptr(), prog_type as u32) };
        debug_assert!(util::parse_ret(rc).is_ok(), "{rc}");
    }

    pub fn set_attach_type(&mut self, attach_type: ProgramAttachType) {
        let rc = unsafe {
            libbpf_sys::bpf_program__set_expected_attach_type(self.ptr.as_ptr(), attach_type as u32)
        };
        debug_assert!(util::parse_ret(rc).is_ok(), "{rc}");
    }

    pub fn set_ifindex(&mut self, idx: u32) {
        unsafe { libbpf_sys::bpf_program__set_ifindex(self.ptr.as_ptr(), idx) }
    }

    /// Set the log level for the bpf program.
    ///
    /// The log level is interpreted by bpf kernel code and interpretation may
    /// change with newer kernel versions. Refer to the kernel source code for
    /// details.
    ///
    /// In general, a value of `0` disables logging while values `> 0` enables
    /// it.
    pub fn set_log_level(&mut self, log_level: u32) {
        let rc = unsafe { libbpf_sys::bpf_program__set_log_level(self.ptr.as_ptr(), log_level) };
        debug_assert!(util::parse_ret(rc).is_ok(), "{rc}");
    }

    /// Set whether a bpf program should be automatically loaded by default
    /// when the bpf object is loaded.
    pub fn set_autoload(&mut self, autoload: bool) {
        let rc = unsafe { libbpf_sys::bpf_program__set_autoload(self.ptr.as_ptr(), autoload) };
        debug_assert!(util::parse_ret(rc).is_ok(), "{rc}");
    }

    pub fn set_attach_target(
        &mut self,
        attach_prog_fd: i32,
        attach_func_name: Option<String>,
    ) -> Result<()> {
        let ret = if let Some(name) = attach_func_name {
            // NB: we must hold onto a CString otherwise our pointer dangles
            let name_c = util::str_to_cstring(&name)?;
            unsafe {
                libbpf_sys::bpf_program__set_attach_target(
                    self.ptr.as_ptr(),
                    attach_prog_fd,
                    name_c.as_ptr(),
                )
            }
        } else {
            unsafe {
                libbpf_sys::bpf_program__set_attach_target(
                    self.ptr.as_ptr(),
                    attach_prog_fd,
                    ptr::null(),
                )
            }
        };
        util::parse_ret(ret)
    }

    pub fn set_flags(&mut self, flags: u32) {
        let rc = unsafe { libbpf_sys::bpf_program__set_flags(self.ptr.as_ptr(), flags) };
        debug_assert!(util::parse_ret(rc).is_ok(), "{rc}");
    }
}

impl<'obj> Deref for OpenProgramMut<'obj> {
    type Target = OpenProgram<'obj>;

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

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

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

/// Type of a [`Program`]. Maps to `enum bpf_prog_type` in kernel uapi.
#[non_exhaustive]
#[repr(u32)]
#[derive(Copy, Clone, Debug)]
// TODO: Document variants.
#[allow(missing_docs)]
pub enum ProgramType {
    Unspec = 0,
    SocketFilter,
    Kprobe,
    SchedCls,
    SchedAct,
    Tracepoint,
    Xdp,
    PerfEvent,
    CgroupSkb,
    CgroupSock,
    LwtIn,
    LwtOut,
    LwtXmit,
    SockOps,
    SkSkb,
    CgroupDevice,
    SkMsg,
    RawTracepoint,
    CgroupSockAddr,
    LwtSeg6local,
    LircMode2,
    SkReuseport,
    FlowDissector,
    CgroupSysctl,
    RawTracepointWritable,
    CgroupSockopt,
    Tracing,
    StructOps,
    Ext,
    Lsm,
    SkLookup,
    Syscall,
    /// See [`MapType::Unknown`][crate::MapType::Unknown]
    Unknown = u32::MAX,
}

impl ProgramType {
    /// Detects if host kernel supports this BPF program 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_prog_type(*self as u32, ptr::null()) };
        match ret {
            0 => Ok(false),
            1 => Ok(true),
            _ => Err(Error::from_raw_os_error(-ret)),
        }
    }

    /// Detects if host kernel supports the use of a given BPF helper from this BPF program type.
    /// * `helper_id` - BPF helper ID (enum bpf_func_id) to check support for
    ///
    /// Make sure the process has required set of CAP_* permissions (or runs as
    /// root) when performing feature checking.
    pub fn is_helper_supported(&self, helper_id: bpf_func_id) -> Result<bool> {
        let ret =
            unsafe { libbpf_sys::libbpf_probe_bpf_helper(*self as u32, helper_id, ptr::null()) };
        match ret {
            0 => Ok(false),
            1 => Ok(true),
            _ => Err(Error::from_raw_os_error(-ret)),
        }
    }
}

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

        match value {
            x if x == Unspec as u32 => Unspec,
            x if x == SocketFilter as u32 => SocketFilter,
            x if x == Kprobe as u32 => Kprobe,
            x if x == SchedCls as u32 => SchedCls,
            x if x == SchedAct as u32 => SchedAct,
            x if x == Tracepoint as u32 => Tracepoint,
            x if x == Xdp as u32 => Xdp,
            x if x == PerfEvent as u32 => PerfEvent,
            x if x == CgroupSkb as u32 => CgroupSkb,
            x if x == CgroupSock as u32 => CgroupSock,
            x if x == LwtIn as u32 => LwtIn,
            x if x == LwtOut as u32 => LwtOut,
            x if x == LwtXmit as u32 => LwtXmit,
            x if x == SockOps as u32 => SockOps,
            x if x == SkSkb as u32 => SkSkb,
            x if x == CgroupDevice as u32 => CgroupDevice,
            x if x == SkMsg as u32 => SkMsg,
            x if x == RawTracepoint as u32 => RawTracepoint,
            x if x == CgroupSockAddr as u32 => CgroupSockAddr,
            x if x == LwtSeg6local as u32 => LwtSeg6local,
            x if x == LircMode2 as u32 => LircMode2,
            x if x == SkReuseport as u32 => SkReuseport,
            x if x == FlowDissector as u32 => FlowDissector,
            x if x == CgroupSysctl as u32 => CgroupSysctl,
            x if x == RawTracepointWritable as u32 => RawTracepointWritable,
            x if x == CgroupSockopt as u32 => CgroupSockopt,
            x if x == Tracing as u32 => Tracing,
            x if x == StructOps as u32 => StructOps,
            x if x == Ext as u32 => Ext,
            x if x == Lsm as u32 => Lsm,
            x if x == SkLookup as u32 => SkLookup,
            x if x == Syscall as u32 => Syscall,
            _ => Unknown,
        }
    }
}

/// Attach type of a [`Program`]. Maps to `enum bpf_attach_type` in kernel uapi.
#[non_exhaustive]
#[repr(u32)]
#[derive(Clone, Debug)]
// TODO: Document variants.
#[allow(missing_docs)]
pub enum ProgramAttachType {
    CgroupInetIngress,
    CgroupInetEgress,
    CgroupInetSockCreate,
    CgroupSockOps,
    SkSkbStreamParser,
    SkSkbStreamVerdict,
    CgroupDevice,
    SkMsgVerdict,
    CgroupInet4Bind,
    CgroupInet6Bind,
    CgroupInet4Connect,
    CgroupInet6Connect,
    CgroupInet4PostBind,
    CgroupInet6PostBind,
    CgroupUdp4Sendmsg,
    CgroupUdp6Sendmsg,
    LircMode2,
    FlowDissector,
    CgroupSysctl,
    CgroupUdp4Recvmsg,
    CgroupUdp6Recvmsg,
    CgroupGetsockopt,
    CgroupSetsockopt,
    TraceRawTp,
    TraceFentry,
    TraceFexit,
    ModifyReturn,
    LsmMac,
    TraceIter,
    CgroupInet4Getpeername,
    CgroupInet6Getpeername,
    CgroupInet4Getsockname,
    CgroupInet6Getsockname,
    XdpDevmap,
    CgroupInetSockRelease,
    XdpCpumap,
    SkLookup,
    Xdp,
    SkSkbVerdict,
    SkReuseportSelect,
    SkReuseportSelectOrMigrate,
    PerfEvent,
    /// See [`MapType::Unknown`][crate::MapType::Unknown]
    Unknown = u32::MAX,
}

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

        match value {
            x if x == CgroupInetIngress as u32 => CgroupInetIngress,
            x if x == CgroupInetEgress as u32 => CgroupInetEgress,
            x if x == CgroupInetSockCreate as u32 => CgroupInetSockCreate,
            x if x == CgroupSockOps as u32 => CgroupSockOps,
            x if x == SkSkbStreamParser as u32 => SkSkbStreamParser,
            x if x == SkSkbStreamVerdict as u32 => SkSkbStreamVerdict,
            x if x == CgroupDevice as u32 => CgroupDevice,
            x if x == SkMsgVerdict as u32 => SkMsgVerdict,
            x if x == CgroupInet4Bind as u32 => CgroupInet4Bind,
            x if x == CgroupInet6Bind as u32 => CgroupInet6Bind,
            x if x == CgroupInet4Connect as u32 => CgroupInet4Connect,
            x if x == CgroupInet6Connect as u32 => CgroupInet6Connect,
            x if x == CgroupInet4PostBind as u32 => CgroupInet4PostBind,
            x if x == CgroupInet6PostBind as u32 => CgroupInet6PostBind,
            x if x == CgroupUdp4Sendmsg as u32 => CgroupUdp4Sendmsg,
            x if x == CgroupUdp6Sendmsg as u32 => CgroupUdp6Sendmsg,
            x if x == LircMode2 as u32 => LircMode2,
            x if x == FlowDissector as u32 => FlowDissector,
            x if x == CgroupSysctl as u32 => CgroupSysctl,
            x if x == CgroupUdp4Recvmsg as u32 => CgroupUdp4Recvmsg,
            x if x == CgroupUdp6Recvmsg as u32 => CgroupUdp6Recvmsg,
            x if x == CgroupGetsockopt as u32 => CgroupGetsockopt,
            x if x == CgroupSetsockopt as u32 => CgroupSetsockopt,
            x if x == TraceRawTp as u32 => TraceRawTp,
            x if x == TraceFentry as u32 => TraceFentry,
            x if x == TraceFexit as u32 => TraceFexit,
            x if x == ModifyReturn as u32 => ModifyReturn,
            x if x == LsmMac as u32 => LsmMac,
            x if x == TraceIter as u32 => TraceIter,
            x if x == CgroupInet4Getpeername as u32 => CgroupInet4Getpeername,
            x if x == CgroupInet6Getpeername as u32 => CgroupInet6Getpeername,
            x if x == CgroupInet4Getsockname as u32 => CgroupInet4Getsockname,
            x if x == CgroupInet6Getsockname as u32 => CgroupInet6Getsockname,
            x if x == XdpDevmap as u32 => XdpDevmap,
            x if x == CgroupInetSockRelease as u32 => CgroupInetSockRelease,
            x if x == XdpCpumap as u32 => XdpCpumap,
            x if x == SkLookup as u32 => SkLookup,
            x if x == Xdp as u32 => Xdp,
            x if x == SkSkbVerdict as u32 => SkSkbVerdict,
            x if x == SkReuseportSelect as u32 => SkReuseportSelect,
            x if x == SkReuseportSelectOrMigrate as u32 => SkReuseportSelectOrMigrate,
            x if x == PerfEvent as u32 => PerfEvent,
            _ => Unknown,
        }
    }
}

/// The input a program accepts.
///
/// This type is mostly used in conjunction with the [`Program::test_run`]
/// facility.
#[derive(Debug, Default)]
pub struct Input<'dat> {
    /// The input context to provide.
    ///
    /// The input is mutable because the kernel may modify it.
    pub context_in: Option<&'dat mut [u8]>,
    /// The output context buffer provided to the program.
    pub context_out: Option<&'dat mut [u8]>,
    /// Additional data to provide to the program.
    pub data_in: Option<&'dat [u8]>,
    /// The output data buffer provided to the program.
    pub data_out: Option<&'dat mut [u8]>,
    /// The 'cpu' value passed to the kernel.
    pub cpu: u32,
    /// The 'flags' value passed to the kernel.
    pub flags: u32,
    /// The struct is non-exhaustive and open to extension.
    #[doc(hidden)]
    pub _non_exhaustive: (),
}

/// The output a program produces.
///
/// This type is mostly used in conjunction with the [`Program::test_run`]
/// facility.
#[derive(Debug)]
pub struct Output<'dat> {
    /// The value returned by the program.
    pub return_value: u32,
    /// The output context filled by the program/kernel.
    pub context: Option<&'dat mut [u8]>,
    /// Output data filled by the program.
    pub data: Option<&'dat mut [u8]>,
    /// The struct is non-exhaustive and open to extension.
    #[doc(hidden)]
    pub _non_exhaustive: (),
}

/// An immutable loaded BPF program.
pub type Program<'obj> = ProgramImpl<'obj>;
/// A mutable loaded BPF program.
pub type ProgramMut<'obj> = ProgramImpl<'obj, Mut>;


/// Represents a loaded [`Program`].
///
/// This struct is not safe to clone because the underlying libbpf resource cannot currently
/// be protected from data races.
///
/// If you attempt to attach a `Program` with the wrong attach method, the `attach_*`
/// method will fail with the appropriate error.
#[derive(Debug)]
#[repr(transparent)]
pub struct ProgramImpl<'obj, T = ()> {
    pub(crate) ptr: NonNull<libbpf_sys::bpf_program>,
    _phantom: PhantomData<&'obj T>,
}

impl<'obj> Program<'obj> {
    /// Create a [`Program`] from a [`libbpf_sys::bpf_program`]
    pub fn new(prog: &'obj libbpf_sys::bpf_program) -> Self {
        // SAFETY: We inferred the address from a reference, which is always
        //         valid.
        Self {
            ptr: unsafe { NonNull::new_unchecked(prog as *const _ as *mut _) },
            _phantom: PhantomData,
        }
    }

    /// Retrieve the name of this `Program`.
    pub fn name(&self) -> &OsStr {
        let name_ptr = unsafe { libbpf_sys::bpf_program__name(self.ptr.as_ptr()) };
        let name_c_str = unsafe { CStr::from_ptr(name_ptr) };
        // SAFETY: `bpf_program__name` always returns a non-NULL pointer.
        OsStr::from_bytes(name_c_str.to_bytes())
    }

    /// Retrieve the name of the section this `Program` belongs to.
    pub fn section(&self) -> &OsStr {
        // SAFETY: The program is always valid.
        let p = unsafe { libbpf_sys::bpf_program__section_name(self.ptr.as_ptr()) };
        // SAFETY: `bpf_program__section_name` will always return a non-NULL
        //         pointer.
        let section_c_str = unsafe { CStr::from_ptr(p) };
        let section = OsStr::from_bytes(section_c_str.to_bytes());
        section
    }

    /// Retrieve the type of the program.
    pub fn prog_type(&self) -> ProgramType {
        ProgramType::from(unsafe { libbpf_sys::bpf_program__type(self.ptr.as_ptr()) })
    }

    /// Returns program fd by id
    pub fn get_fd_by_id(id: u32) -> Result<OwnedFd> {
        let ret = unsafe { libbpf_sys::bpf_prog_get_fd_by_id(id) };
        let fd = util::parse_ret_i32(ret)?;
        // SAFETY
        // A file descriptor coming from the bpf_prog_get_fd_by_id function is always suitable for
        // ownership and can be cleaned up with close.
        Ok(unsafe { OwnedFd::from_raw_fd(fd) })
    }

    /// Returns program id by fd
    pub fn get_id_by_fd(fd: BorrowedFd<'_>) -> Result<u32> {
        let mut prog_info = libbpf_sys::bpf_prog_info::default();
        let prog_info_ptr: *mut libbpf_sys::bpf_prog_info = &mut prog_info;
        let mut len = size_of::<libbpf_sys::bpf_prog_info>() as u32;
        let ret = unsafe {
            libbpf_sys::bpf_obj_get_info_by_fd(
                fd.as_raw_fd(),
                prog_info_ptr as *mut c_void,
                &mut len,
            )
        };
        util::parse_ret(ret)?;
        Ok(prog_info.id)
    }

    /// Returns flags that have been set for the program.
    pub fn flags(&self) -> u32 {
        unsafe { libbpf_sys::bpf_program__flags(self.ptr.as_ptr()) }
    }

    /// Retrieve the attach type of the program.
    pub fn attach_type(&self) -> ProgramAttachType {
        ProgramAttachType::from(unsafe {
            libbpf_sys::bpf_program__expected_attach_type(self.ptr.as_ptr())
        })
    }

    /// Return `true` if the bpf program is set to autoload, `false` otherwise.
    pub fn autoload(&self) -> bool {
        unsafe { libbpf_sys::bpf_program__autoload(self.ptr.as_ptr()) }
    }

    /// Return the bpf program's log level.
    pub fn log_level(&self) -> u32 {
        unsafe { libbpf_sys::bpf_program__log_level(self.ptr.as_ptr()) }
    }

    /// Returns the number of instructions that form the program.
    ///
    /// Please see note in [`OpenProgram::insn_cnt`].
    pub fn insn_cnt(&self) -> usize {
        unsafe { libbpf_sys::bpf_program__insn_cnt(self.ptr.as_ptr()) as usize }
    }

    /// Gives read-only access to BPF program's underlying BPF instructions.
    ///
    /// Please see note in [`OpenProgram::insns`].
    pub fn insns(&self) -> &[libbpf_sys::bpf_insn] {
        let count = self.insn_cnt();
        let ptr = unsafe { libbpf_sys::bpf_program__insns(self.ptr.as_ptr()) };
        unsafe { slice::from_raw_parts(ptr, count) }
    }
}

impl<'obj> ProgramMut<'obj> {
    /// Create a [`Program`] from a [`libbpf_sys::bpf_program`]
    pub fn new_mut(prog: &'obj mut libbpf_sys::bpf_program) -> Self {
        Self {
            ptr: unsafe { NonNull::new_unchecked(prog as *mut _) },
            _phantom: PhantomData,
        }
    }

    /// [Pin](https://facebookmicrosites.github.io/bpf/blog/2018/08/31/object-lifetime.html#bpffs)
    /// this program 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_program__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 program 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_program__unpin(self.ptr.as_ptr(), path_ptr) };
        util::parse_ret(ret)
    }

    /// Auto-attach based on prog section
    pub fn attach(&mut self) -> Result<Link> {
        let ptr = unsafe { libbpf_sys::bpf_program__attach(self.ptr.as_ptr()) };
        let ptr = validate_bpf_ret(ptr).context("failed to attach BPF program")?;
        // SAFETY: the pointer came from libbpf and has been checked for errors.
        let link = unsafe { Link::new(ptr) };
        Ok(link)
    }

    /// Attach this program to a
    /// [cgroup](https://www.kernel.org/doc/html/latest/admin-guide/cgroup-v2.html).
    pub fn attach_cgroup(&mut self, cgroup_fd: i32) -> Result<Link> {
        let ptr = unsafe { libbpf_sys::bpf_program__attach_cgroup(self.ptr.as_ptr(), cgroup_fd) };
        let ptr = validate_bpf_ret(ptr).context("failed to attach cgroup")?;
        // SAFETY: the pointer came from libbpf and has been checked for errors.
        let link = unsafe { Link::new(ptr) };
        Ok(link)
    }

    /// Attach this program to a [perf event](https://linux.die.net/man/2/perf_event_open).
    pub fn attach_perf_event(&mut self, pfd: i32) -> Result<Link> {
        let ptr = unsafe { libbpf_sys::bpf_program__attach_perf_event(self.ptr.as_ptr(), pfd) };
        let ptr = validate_bpf_ret(ptr).context("failed to attach perf event")?;
        // SAFETY: the pointer came from libbpf and has been checked for errors.
        let link = unsafe { Link::new(ptr) };
        Ok(link)
    }

    /// Attach this program to a [userspace
    /// probe](https://www.kernel.org/doc/html/latest/trace/uprobetracer.html).
    pub fn attach_uprobe<T: AsRef<Path>>(
        &mut self,
        retprobe: bool,
        pid: i32,
        binary_path: T,
        func_offset: usize,
    ) -> Result<Link> {
        let path = util::path_to_cstring(binary_path)?;
        let path_ptr = path.as_ptr();
        let ptr = unsafe {
            libbpf_sys::bpf_program__attach_uprobe(
                self.ptr.as_ptr(),
                retprobe,
                pid,
                path_ptr,
                func_offset as libbpf_sys::size_t,
            )
        };
        let ptr = validate_bpf_ret(ptr).context("failed to attach uprobe")?;
        // SAFETY: the pointer came from libbpf and has been checked for errors.
        let link = unsafe { Link::new(ptr) };
        Ok(link)
    }

    /// Attach this program to a [userspace
    /// probe](https://www.kernel.org/doc/html/latest/trace/uprobetracer.html),
    /// providing additional options.
    pub fn attach_uprobe_with_opts(
        &mut self,
        pid: i32,
        binary_path: impl AsRef<Path>,
        func_offset: usize,
        opts: UprobeOpts,
    ) -> Result<Link> {
        let path = util::path_to_cstring(binary_path)?;
        let path_ptr = path.as_ptr();
        let UprobeOpts {
            ref_ctr_offset,
            cookie,
            retprobe,
            func_name,
            _non_exhaustive,
        } = opts;

        let func_name = util::str_to_cstring(&func_name)?;
        let opts = libbpf_sys::bpf_uprobe_opts {
            sz: size_of::<libbpf_sys::bpf_uprobe_opts>() as _,
            ref_ctr_offset: ref_ctr_offset as libbpf_sys::size_t,
            bpf_cookie: cookie,
            retprobe,
            func_name: func_name.as_ptr(),
            ..Default::default()
        };

        let ptr = unsafe {
            libbpf_sys::bpf_program__attach_uprobe_opts(
                self.ptr.as_ptr(),
                pid,
                path_ptr,
                func_offset as libbpf_sys::size_t,
                &opts as *const _,
            )
        };
        let ptr = validate_bpf_ret(ptr).context("failed to attach uprobe")?;
        // SAFETY: the pointer came from libbpf and has been checked for errors.
        let link = unsafe { Link::new(ptr) };
        Ok(link)
    }

    /// Attach this program to a [kernel
    /// probe](https://www.kernel.org/doc/html/latest/trace/kprobetrace.html).
    pub fn attach_kprobe<T: AsRef<str>>(&mut self, retprobe: bool, func_name: T) -> Result<Link> {
        let func_name = util::str_to_cstring(func_name.as_ref())?;
        let func_name_ptr = func_name.as_ptr();
        let ptr = unsafe {
            libbpf_sys::bpf_program__attach_kprobe(self.ptr.as_ptr(), retprobe, func_name_ptr)
        };
        let ptr = validate_bpf_ret(ptr).context("failed to attach kprobe")?;
        // SAFETY: the pointer came from libbpf and has been checked for errors.
        let link = unsafe { Link::new(ptr) };
        Ok(link)
    }

    /// Attach this program to the specified syscall
    pub fn attach_ksyscall<T: AsRef<str>>(
        &mut self,
        retprobe: bool,
        syscall_name: T,
    ) -> Result<Link> {
        let opts = libbpf_sys::bpf_ksyscall_opts {
            sz: size_of::<libbpf_sys::bpf_ksyscall_opts>() as _,
            retprobe,
            ..Default::default()
        };

        let syscall_name = util::str_to_cstring(syscall_name.as_ref())?;
        let syscall_name_ptr = syscall_name.as_ptr();
        let ptr = unsafe {
            libbpf_sys::bpf_program__attach_ksyscall(self.ptr.as_ptr(), syscall_name_ptr, &opts)
        };
        let ptr = validate_bpf_ret(ptr).context("failed to attach ksyscall")?;
        // SAFETY: the pointer came from libbpf and has been checked for errors.
        let link = unsafe { Link::new(ptr) };
        Ok(link)
    }

    fn attach_tracepoint_impl(
        &mut self,
        tp_category: &str,
        tp_name: &str,
        tp_opts: Option<TracepointOpts>,
    ) -> Result<Link> {
        let tp_category = util::str_to_cstring(tp_category)?;
        let tp_category_ptr = tp_category.as_ptr();
        let tp_name = util::str_to_cstring(tp_name)?;
        let tp_name_ptr = tp_name.as_ptr();

        let ptr = if let Some(tp_opts) = tp_opts {
            let tp_opts = libbpf_sys::bpf_tracepoint_opts::from(tp_opts);
            unsafe {
                libbpf_sys::bpf_program__attach_tracepoint_opts(
                    self.ptr.as_ptr(),
                    tp_category_ptr,
                    tp_name_ptr,
                    &tp_opts as *const _,
                )
            }
        } else {
            unsafe {
                libbpf_sys::bpf_program__attach_tracepoint(
                    self.ptr.as_ptr(),
                    tp_category_ptr,
                    tp_name_ptr,
                )
            }
        };

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

    /// Attach this program to a [kernel
    /// tracepoint](https://www.kernel.org/doc/html/latest/trace/tracepoints.html).
    pub fn attach_tracepoint(
        &mut self,
        tp_category: impl AsRef<str>,
        tp_name: impl AsRef<str>,
    ) -> Result<Link> {
        self.attach_tracepoint_impl(tp_category.as_ref(), tp_name.as_ref(), None)
    }

    /// Attach this program to a [kernel
    /// tracepoint](https://www.kernel.org/doc/html/latest/trace/tracepoints.html),
    /// providing additional options.
    pub fn attach_tracepoint_with_opts(
        &mut self,
        tp_category: impl AsRef<str>,
        tp_name: impl AsRef<str>,
        tp_opts: TracepointOpts,
    ) -> Result<Link> {
        self.attach_tracepoint_impl(tp_category.as_ref(), tp_name.as_ref(), Some(tp_opts))
    }

    /// Attach this program to a [raw kernel
    /// tracepoint](https://lwn.net/Articles/748352/).
    pub fn attach_raw_tracepoint<T: AsRef<str>>(&mut self, tp_name: T) -> Result<Link> {
        let tp_name = util::str_to_cstring(tp_name.as_ref())?;
        let tp_name_ptr = tp_name.as_ptr();
        let ptr = unsafe {
            libbpf_sys::bpf_program__attach_raw_tracepoint(self.ptr.as_ptr(), tp_name_ptr)
        };
        let ptr = validate_bpf_ret(ptr).context("failed to attach raw tracepoint")?;
        // SAFETY: the pointer came from libbpf and has been checked for errors.
        let link = unsafe { Link::new(ptr) };
        Ok(link)
    }

    /// Attach to an [LSM](https://en.wikipedia.org/wiki/Linux_Security_Modules) hook
    pub fn attach_lsm(&mut self) -> Result<Link> {
        let ptr = unsafe { libbpf_sys::bpf_program__attach_lsm(self.ptr.as_ptr()) };
        let ptr = validate_bpf_ret(ptr).context("failed to attach LSM")?;
        // SAFETY: the pointer came from libbpf and has been checked for errors.
        let link = unsafe { Link::new(ptr) };
        Ok(link)
    }

    /// Attach to a [fentry/fexit kernel probe](https://lwn.net/Articles/801479/)
    pub fn attach_trace(&mut self) -> Result<Link> {
        let ptr = unsafe { libbpf_sys::bpf_program__attach_trace(self.ptr.as_ptr()) };
        let ptr = validate_bpf_ret(ptr).context("failed to attach fentry/fexit kernel probe")?;
        // SAFETY: the pointer came from libbpf and has been checked for errors.
        let link = unsafe { Link::new(ptr) };
        Ok(link)
    }

    /// Attach a verdict/parser to a [sockmap/sockhash](https://lwn.net/Articles/731133/)
    pub fn attach_sockmap(&self, map_fd: i32) -> Result<()> {
        let err = unsafe {
            libbpf_sys::bpf_prog_attach(
                self.as_fd().as_raw_fd(),
                map_fd,
                self.attach_type() as u32,
                0,
            )
        };
        util::parse_ret(err)
    }

    /// Attach this program to [XDP](https://lwn.net/Articles/825998/)
    pub fn attach_xdp(&mut self, ifindex: i32) -> Result<Link> {
        let ptr = unsafe { libbpf_sys::bpf_program__attach_xdp(self.ptr.as_ptr(), ifindex) };
        let ptr = validate_bpf_ret(ptr).context("failed to attach XDP program")?;
        // SAFETY: the pointer came from libbpf and has been checked for errors.
        let link = unsafe { Link::new(ptr) };
        Ok(link)
    }

    /// Attach this program to [netns-based programs](https://lwn.net/Articles/819618/)
    pub fn attach_netns(&mut self, netns_fd: i32) -> Result<Link> {
        let ptr = unsafe { libbpf_sys::bpf_program__attach_netns(self.ptr.as_ptr(), netns_fd) };
        let ptr = validate_bpf_ret(ptr).context("failed to attach network namespace program")?;
        // SAFETY: the pointer came from libbpf and has been checked for errors.
        let link = unsafe { Link::new(ptr) };
        Ok(link)
    }

    fn attach_usdt_impl(
        &mut self,
        pid: i32,
        binary_path: &Path,
        usdt_provider: &str,
        usdt_name: &str,
        usdt_opts: Option<UsdtOpts>,
    ) -> Result<Link> {
        let path = util::path_to_cstring(binary_path)?;
        let path_ptr = path.as_ptr();
        let usdt_provider = util::str_to_cstring(usdt_provider)?;
        let usdt_provider_ptr = usdt_provider.as_ptr();
        let usdt_name = util::str_to_cstring(usdt_name)?;
        let usdt_name_ptr = usdt_name.as_ptr();
        let usdt_opts = usdt_opts.map(libbpf_sys::bpf_usdt_opts::from);
        let usdt_opts_ptr = usdt_opts
            .as_ref()
            .map(|opts| opts as *const _)
            .unwrap_or_else(ptr::null);

        let ptr = unsafe {
            libbpf_sys::bpf_program__attach_usdt(
                self.ptr.as_ptr(),
                pid,
                path_ptr,
                usdt_provider_ptr,
                usdt_name_ptr,
                usdt_opts_ptr,
            )
        };
        let ptr = validate_bpf_ret(ptr).context("failed to attach USDT")?;
        // SAFETY: the pointer came from libbpf and has been checked for errors.
        let link = unsafe { Link::new(ptr) };
        Ok(link)
    }

    /// Attach this program to a [USDT](https://lwn.net/Articles/753601/) probe
    /// point. The entry point of the program must be defined with
    /// `SEC("usdt")`.
    pub fn attach_usdt(
        &mut self,
        pid: i32,
        binary_path: impl AsRef<Path>,
        usdt_provider: impl AsRef<str>,
        usdt_name: impl AsRef<str>,
    ) -> Result<Link> {
        self.attach_usdt_impl(
            pid,
            binary_path.as_ref(),
            usdt_provider.as_ref(),
            usdt_name.as_ref(),
            None,
        )
    }

    /// Attach this program to a [USDT](https://lwn.net/Articles/753601/) probe
    /// point, providing additional options. The entry point of the program must
    /// be defined with `SEC("usdt")`.
    pub fn attach_usdt_with_opts(
        &mut self,
        pid: i32,
        binary_path: impl AsRef<Path>,
        usdt_provider: impl AsRef<str>,
        usdt_name: impl AsRef<str>,
        usdt_opts: UsdtOpts,
    ) -> Result<Link> {
        self.attach_usdt_impl(
            pid,
            binary_path.as_ref(),
            usdt_provider.as_ref(),
            usdt_name.as_ref(),
            Some(usdt_opts),
        )
    }

    /// Attach this program to a
    /// [BPF Iterator](https://www.kernel.org/doc/html/latest/bpf/bpf_iterators.html).
    /// The entry point of the program must be defined with `SEC("iter")` or `SEC("iter.s")`.
    pub fn attach_iter(&mut self, map_fd: BorrowedFd<'_>) -> Result<Link> {
        let mut linkinfo = libbpf_sys::bpf_iter_link_info::default();
        linkinfo.map.map_fd = map_fd.as_raw_fd() as _;
        let attach_opt = libbpf_sys::bpf_iter_attach_opts {
            link_info: &mut linkinfo as *mut libbpf_sys::bpf_iter_link_info,
            link_info_len: size_of::<libbpf_sys::bpf_iter_link_info>() as _,
            sz: size_of::<libbpf_sys::bpf_iter_attach_opts>() as _,
            ..Default::default()
        };
        let ptr = unsafe {
            libbpf_sys::bpf_program__attach_iter(
                self.ptr.as_ptr(),
                &attach_opt as *const libbpf_sys::bpf_iter_attach_opts,
            )
        };

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

    /// Test run the program with the given input data.
    ///
    /// This function uses the
    /// [BPF_PROG_RUN](https://www.kernel.org/doc/html/latest/bpf/bpf_prog_run.html)
    /// facility.
    pub fn test_run<'dat>(&mut self, input: Input<'dat>) -> Result<Output<'dat>> {
        unsafe fn slice_from_array<'t, T>(items: *mut T, num_items: usize) -> Option<&'t mut [T]> {
            if items.is_null() {
                None
            } else {
                Some(unsafe { slice::from_raw_parts_mut(items, num_items) })
            }
        }

        let Input {
            context_in,
            mut context_out,
            data_in,
            mut data_out,
            cpu,
            flags,
            _non_exhaustive: (),
        } = input;

        let mut opts = unsafe { mem::zeroed::<libbpf_sys::bpf_test_run_opts>() };
        opts.sz = size_of_val(&opts) as _;
        opts.ctx_in = context_in
            .as_ref()
            .map(|data| data.as_ptr().cast())
            .unwrap_or_else(ptr::null);
        opts.ctx_size_in = context_in.map(|data| data.len() as _).unwrap_or(0);
        opts.ctx_out = context_out
            .as_mut()
            .map(|data| data.as_mut_ptr().cast())
            .unwrap_or_else(ptr::null_mut);
        opts.ctx_size_out = context_out.map(|data| data.len() as _).unwrap_or(0);
        opts.data_in = data_in
            .map(|data| data.as_ptr().cast())
            .unwrap_or_else(ptr::null);
        opts.data_size_in = data_in.map(|data| data.len() as _).unwrap_or(0);
        opts.data_out = data_out
            .as_mut()
            .map(|data| data.as_mut_ptr().cast())
            .unwrap_or_else(ptr::null_mut);
        opts.data_size_out = data_out.map(|data| data.len() as _).unwrap_or(0);
        opts.cpu = cpu;
        opts.flags = flags;

        let rc = unsafe { libbpf_sys::bpf_prog_test_run_opts(self.as_fd().as_raw_fd(), &mut opts) };
        let () = util::parse_ret(rc)?;
        let output = Output {
            return_value: opts.retval,
            context: unsafe { slice_from_array(opts.ctx_out.cast(), opts.ctx_size_out as _) },
            data: unsafe { slice_from_array(opts.data_out.cast(), opts.data_size_out as _) },
            _non_exhaustive: (),
        };
        Ok(output)
    }
}

impl<'obj> Deref for ProgramMut<'obj> {
    type Target = Program<'obj>;

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

impl<T> AsFd for ProgramImpl<'_, T> {
    fn as_fd(&self) -> BorrowedFd<'_> {
        let fd = unsafe { libbpf_sys::bpf_program__fd(self.ptr.as_ptr()) };
        unsafe { BorrowedFd::borrow_raw(fd) }
    }
}

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

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

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

    use std::mem::discriminant;

    #[test]
    fn program_type() {
        use ProgramType::*;

        for t in [
            Unspec,
            SocketFilter,
            Kprobe,
            SchedCls,
            SchedAct,
            Tracepoint,
            Xdp,
            PerfEvent,
            CgroupSkb,
            CgroupSock,
            LwtIn,
            LwtOut,
            LwtXmit,
            SockOps,
            SkSkb,
            CgroupDevice,
            SkMsg,
            RawTracepoint,
            CgroupSockAddr,
            LwtSeg6local,
            LircMode2,
            SkReuseport,
            FlowDissector,
            CgroupSysctl,
            RawTracepointWritable,
            CgroupSockopt,
            Tracing,
            StructOps,
            Ext,
            Lsm,
            SkLookup,
            Syscall,
            Unknown,
        ] {
            // check if discriminants match after a roundtrip conversion
            assert_eq!(discriminant(&t), discriminant(&ProgramType::from(t as u32)));
        }
    }

    #[test]
    fn program_attach_type() {
        use ProgramAttachType::*;

        for t in [
            CgroupInetIngress,
            CgroupInetEgress,
            CgroupInetSockCreate,
            CgroupSockOps,
            SkSkbStreamParser,
            SkSkbStreamVerdict,
            CgroupDevice,
            SkMsgVerdict,
            CgroupInet4Bind,
            CgroupInet6Bind,
            CgroupInet4Connect,
            CgroupInet6Connect,
            CgroupInet4PostBind,
            CgroupInet6PostBind,
            CgroupUdp4Sendmsg,
            CgroupUdp6Sendmsg,
            LircMode2,
            FlowDissector,
            CgroupSysctl,
            CgroupUdp4Recvmsg,
            CgroupUdp6Recvmsg,
            CgroupGetsockopt,
            CgroupSetsockopt,
            TraceRawTp,
            TraceFentry,
            TraceFexit,
            ModifyReturn,
            LsmMac,
            TraceIter,
            CgroupInet4Getpeername,
            CgroupInet6Getpeername,
            CgroupInet4Getsockname,
            CgroupInet6Getsockname,
            XdpDevmap,
            CgroupInetSockRelease,
            XdpCpumap,
            SkLookup,
            Xdp,
            SkSkbVerdict,
            SkReuseportSelect,
            SkReuseportSelectOrMigrate,
            PerfEvent,
            Unknown,
        ] {
            // check if discriminants match after a roundtrip conversion
            assert_eq!(
                discriminant(&t),
                discriminant(&ProgramAttachType::from(t as u32))
            );
        }
    }
}
