//! An API for interfacing with `kqueue`.

use crate::fd::{AsFd, AsRawFd, OwnedFd, RawFd};
use crate::{backend, io};

use backend::c::{self, kevent as kevent_t, uintptr_t};
use backend::io::syscalls;

#[cfg(any(apple, freebsdlike))]
use backend::c::intptr_t;

use alloc::vec::Vec;
use core::ptr::slice_from_raw_parts_mut;
use core::time::Duration;

/// A `kqueue` event.
#[repr(transparent)]
#[derive(Copy, Clone)]
pub struct Event {
    // The layout varies between BSDs and macOS.
    inner: kevent_t,
}

impl Event {
    /// Create a new `Event`.
    #[allow(clippy::needless_update)]
    pub fn new(filter: EventFilter, flags: EventFlags, udata: isize) -> Event {
        let (ident, filter, fflags) = match filter {
            EventFilter::Read(fd) => (fd.as_raw_fd() as uintptr_t, c::EVFILT_READ, 0),
            EventFilter::Write(fd) => (fd.as_raw_fd() as _, c::EVFILT_WRITE, 0),
            #[cfg(target_os = "freebsd")]
            EventFilter::Empty(fd) => (fd.as_raw_fd() as _, c::EVFILT_EMPTY, 0),
            EventFilter::Vnode { vnode, flags } => {
                (vnode.as_raw_fd() as _, c::EVFILT_VNODE, flags.bits())
            }
            #[cfg(feature = "process")]
            EventFilter::Proc { pid, flags } => (
                crate::process::Pid::as_raw(Some(pid)) as _,
                c::EVFILT_PROC,
                flags.bits(),
            ),
            #[cfg(feature = "process")]
            EventFilter::Signal { signal, times: _ } => (signal as _, c::EVFILT_SIGNAL, 0),
            EventFilter::Timer(timer) => {
                #[cfg(any(apple, target_os = "freebsd", target_os = "netbsd"))]
                let (data, fflags) = match timer {
                    Some(timer) => {
                        if timer.subsec_millis() == 0 {
                            (timer.as_secs() as _, c::NOTE_SECONDS)
                        } else if timer.subsec_nanos() == 0 {
                            (timer.as_micros() as _, c::NOTE_USECONDS)
                        } else {
                            (timer.as_nanos() as _, c::NOTE_NSECONDS)
                        }
                    }
                    None => (uintptr_t::MAX, c::NOTE_SECONDS),
                };
                #[cfg(any(target_os = "dragonfly", target_os = "openbsd"))]
                let (data, fflags) = match timer {
                    Some(timer) => (timer.as_millis() as _, 0),
                    None => (uintptr_t::MAX, 0),
                };

                (data, c::EVFILT_TIMER, fflags)
            }
            #[cfg(any(apple, freebsdlike))]
            EventFilter::User {
                ident,
                flags,
                user_flags,
            } => (ident as _, c::EVFILT_USER, flags.bits() | user_flags.0),
            EventFilter::Unknown => panic!("unknown filter"),
        };

        Event {
            inner: kevent_t {
                ident,
                filter: filter as _,
                flags: flags.bits() as _,
                fflags,
                data: 0,
                udata: {
                    // On netbsd, udata is an isize and not a pointer.
                    // TODO: Strict provenance, prevent int-to-ptr cast.
                    udata as _
                },
                ..unsafe { core::mem::zeroed() }
            },
        }
    }

    /// Get the event flags for this event.
    pub fn flags(&self) -> EventFlags {
        EventFlags::from_bits_truncate(self.inner.flags as _)
    }

    /// Get the user data for this event.
    pub fn udata(&self) -> isize {
        // On netbsd, udata is an isize and not a pointer.
        // TODO: Strict provenance, prevent ptr-to-int cast.

        self.inner.udata as _
    }

    /// Get the filter of this event.
    pub fn filter(&self) -> EventFilter {
        match self.inner.filter as _ {
            c::EVFILT_READ => EventFilter::Read(self.inner.ident as _),
            c::EVFILT_WRITE => EventFilter::Write(self.inner.ident as _),
            #[cfg(target_os = "freebsd")]
            c::EVFILT_EMPTY => EventFilter::Empty(self.inner.ident as _),
            c::EVFILT_VNODE => EventFilter::Vnode {
                vnode: self.inner.ident as _,
                flags: VnodeEvents::from_bits_truncate(self.inner.fflags),
            },
            #[cfg(feature = "process")]
            c::EVFILT_PROC => EventFilter::Proc {
                pid: unsafe { crate::process::Pid::from_raw(self.inner.ident as _) }.unwrap(),
                flags: ProcessEvents::from_bits_truncate(self.inner.fflags),
            },
            #[cfg(feature = "process")]
            c::EVFILT_SIGNAL => EventFilter::Signal {
                signal: crate::process::Signal::from_raw(self.inner.ident as _).unwrap(),
                times: self.inner.data as _,
            },
            c::EVFILT_TIMER => EventFilter::Timer({
                let (data, fflags) = (self.inner.data, self.inner.fflags);
                #[cfg(any(apple, target_os = "freebsd", target_os = "netbsd"))]
                match fflags as _ {
                    c::NOTE_SECONDS => Some(Duration::from_secs(data as _)),
                    c::NOTE_USECONDS => Some(Duration::from_micros(data as _)),
                    c::NOTE_NSECONDS => Some(Duration::from_nanos(data as _)),
                    _ => {
                        // Unknown timer flags.
                        None
                    }
                }
                #[cfg(any(target_os = "dragonfly", target_os = "openbsd"))]
                Some(Duration::from_millis(data as _))
            }),
            #[cfg(any(apple, freebsdlike))]
            c::EVFILT_USER => EventFilter::User {
                ident: self.inner.ident as _,
                flags: UserFlags::from_bits_truncate(self.inner.fflags),
                user_flags: UserDefinedFlags(self.inner.fflags & EVFILT_USER_FLAGS),
            },
            _ => EventFilter::Unknown,
        }
    }
}

/// Bottom 24 bits of a u32.
#[cfg(any(apple, freebsdlike))]
const EVFILT_USER_FLAGS: u32 = 0x00ff_ffff;

/// The possible filters for a `kqueue`.
#[repr(i16)]
#[non_exhaustive]
pub enum EventFilter {
    /// A read filter.
    Read(RawFd),

    /// A write filter.
    Write(RawFd),

    /// An empty filter.
    #[cfg(target_os = "freebsd")]
    Empty(RawFd),

    /// A VNode filter.
    Vnode {
        /// The file descriptor we looked for events in.
        vnode: RawFd,

        /// The flags for this event.
        flags: VnodeEvents,
    },

    /// A process filter.
    #[cfg(feature = "process")]
    Proc {
        /// The process ID we waited on.
        pid: crate::process::Pid,

        /// The flags for this event.
        flags: ProcessEvents,
    },

    /// A signal filter.
    #[cfg(feature = "process")]
    Signal {
        /// The signal number we waited on.
        signal: crate::process::Signal,

        /// The number of times the signal has been
        /// received since the last call to kevent.
        times: usize,
    },

    /// A timer filter.
    Timer(Option<Duration>),

    /// A user filter.
    #[cfg(any(apple, freebsdlike))]
    User {
        /// The identifier for this event.
        ident: intptr_t,

        /// The flags for this event.
        flags: UserFlags,

        /// The user-defined flags for this event.
        user_flags: UserDefinedFlags,
    },

    /// This filter is unknown.
    ///
    /// # Panics
    ///
    /// Passing this into `Event::new()` will result in a panic.
    Unknown,
}

bitflags::bitflags! {
    /// The flags for a `kqueue` event.
    pub struct EventFlags: u16 {
        /// Add the event to the `kqueue`.
        const ADD = c::EV_ADD as _;

        /// Enable the event.
        const ENABLE = c::EV_ENABLE as _;

        /// Disable the event.
        const DISABLE = c::EV_DISABLE as _;

        /// Delete the event from the `kqueue`.
        const DELETE = c::EV_DELETE as _;

        /// TODO
        const RECEIPT = c::EV_RECEIPT as _;

        /// Clear the event after it is triggered.
        const ONESHOT = c::EV_ONESHOT as _;

        /// TODO
        const CLEAR = c::EV_CLEAR as _;

        /// TODO
        const EOF = c::EV_EOF as _;

        /// TODO
        const ERROR = c::EV_ERROR as _;
    }
}

bitflags::bitflags! {
    /// The flags for a virtual node event.
    pub struct VnodeEvents: u32 {
        /// The file was deleted.
        const DELETE = c::NOTE_DELETE;

        /// The file was written to.
        const WRITE = c::NOTE_WRITE;

        /// The file was extended.
        const EXTEND = c::NOTE_EXTEND;

        /// The file had its attributes changed.
        const ATTRIBUTES = c::NOTE_ATTRIB;

        /// The file was renamed.
        const RENAME = c::NOTE_RENAME;

        /// Access to the file was revoked.
        const REVOKE = c::NOTE_REVOKE;

        /// The link count of the file has changed.
        const LINK = c::NOTE_LINK;
    }
}

#[cfg(feature = "process")]
bitflags::bitflags! {
    /// The flags for a process event.
    pub struct ProcessEvents: u32 {
        /// The process exited.
        const EXIT = c::NOTE_EXIT;

        /// The process forked itself.
        const FORK = c::NOTE_FORK;

        /// The process executed a new process.
        const EXEC = c::NOTE_EXEC;

        /// Follow the process through fork() calls (write only).
        const TRACK = c::NOTE_TRACK;

        /// An error has occurred with following the process.
        const TRACKERR = c::NOTE_TRACKERR;
    }
}

#[cfg(any(apple, freebsdlike))]
bitflags::bitflags! {
    /// The flags for a user event.
    pub struct UserFlags: u32 {
        /// Ignore the user input flags.
        const NOINPUT = c::NOTE_FFNOP;

        /// Bitwise AND fflags.
        const AND = c::NOTE_FFAND;

        /// Bitwise OR fflags.
        const OR = c::NOTE_FFOR;

        /// Copy fflags.
        const COPY = c::NOTE_FFCOPY;

        /// Control mask for operations.
        const CTRLMASK = c::NOTE_FFCTRLMASK;

        /// User defined flags for masks.
        const UDFMASK = c::NOTE_FFLAGSMASK;

        /// Trigger the event.
        const TRIGGER = c::NOTE_TRIGGER;
    }
}

/// User-defined flags.
///
/// Only the lower 24 bits are used in this struct.
#[repr(transparent)]
#[cfg(any(apple, freebsdlike))]
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct UserDefinedFlags(u32);

#[cfg(any(apple, freebsdlike))]
impl UserDefinedFlags {
    /// Create a new `UserDefinedFlags` from a `u32`.
    pub fn new(flags: u32) -> Self {
        Self(flags & EVFILT_USER_FLAGS)
    }

    /// Get the underlying `u32`.
    pub fn get(self) -> u32 {
        self.0
    }
}

/// `kqueue()`—Create a new `kqueue` file descriptor.
///
/// # References
///  - [Apple]
///  - [FreeBSD]
///  - [OpenBSD]
///  - [NetBSD]
///  - [DragonflyBSD]
///
/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/kqueue.2.html
/// [FreeBSD]: https://www.freebsd.org/cgi/man.cgi?query=kqueue&sektion=2
/// [OpenBSD]: https://man.openbsd.org/kqueue.2
/// [NetBSD]: https://man.netbsd.org/kqueue.2
/// [DragonflyBSD]: https://www.dragonflybsd.org/cgi/web-man/?command=kqueue
pub fn kqueue() -> io::Result<OwnedFd> {
    syscalls::kqueue()
}

/// `kevent(kqueue, changelist, eventlist, timeout)`—Wait for events on a
/// `kqueue`.
///
/// Note: in order to receive events, make sure to allocate capacity in the
/// eventlist! Otherwise, the function will return immediately.
///
/// # Safety
///
/// The file descriptors referred to by the `Event` structs must be valid for
/// the lifetime of the `kqueue` file descriptor.
///
/// # References
///  - [Apple]
///  - [FreeBSD]
///  - [OpenBSD]
///  - [NetBSD]
///  - [DragonflyBSD]
///
/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/kevent.2.html
/// [FreeBSD]: https://www.freebsd.org/cgi/man.cgi?query=kevent&sektion=2
/// [OpenBSD]: https://man.openbsd.org/kevent.2
/// [NetBSD]: https://man.netbsd.org/kevent.2
/// [DragonflyBSD]: https://www.dragonflybsd.org/cgi/web-man/?command=kevent
pub unsafe fn kevent(
    kqueue: impl AsFd,
    changelist: &[Event],
    eventlist: &mut Vec<Event>,
    timeout: Option<Duration>,
) -> io::Result<usize> {
    let timeout = timeout.map(|timeout| crate::backend::c::timespec {
        tv_sec: timeout.as_secs() as _,
        tv_nsec: timeout.subsec_nanos() as _,
    });

    // Populate the event list with events.
    eventlist.set_len(0);
    let out_slice =
        slice_from_raw_parts_mut(eventlist.as_mut_ptr() as *mut _, eventlist.capacity());
    let res = syscalls::kevent(
        kqueue.as_fd(),
        changelist,
        &mut *out_slice,
        timeout.as_ref(),
    )
    .map(|res| res as _);

    // Update the event list.
    if let Ok(len) = res {
        eventlist.set_len(len);
    }

    res
}
