//! Monitoring API for filesystem events.
//!
//! Fanotify is a Linux-only API to monitor filesystems events.
//!
//! Additional capabilities compared to the `inotify` API include the ability to
//! monitor all of the objects in a mounted filesystem, the ability to make
//! access permission decisions, and the possibility to read or modify files
//! before access by other applications.
//!
//! For more documentation, please read
//! [fanotify(7)](https://man7.org/linux/man-pages/man7/fanotify.7.html).

use crate::errno::Errno;
use crate::fcntl::{at_rawfd, OFlag};
use crate::unistd::{close, read, write};
use crate::{NixPath, Result};
use std::marker::PhantomData;
use std::mem::{size_of, MaybeUninit};
use std::os::unix::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, OwnedFd, RawFd};
use std::ptr;

libc_bitflags! {
    /// Mask for defining which events shall be listened with
    /// [`fanotify_mark`](fn.fanotify_mark.html) and for querying notifications.
    pub struct MaskFlags: u64 {
        /// File was accessed.
        FAN_ACCESS;
        /// File was modified.
        FAN_MODIFY;
        /// Metadata has changed. Since Linux 5.1.
        FAN_ATTRIB;
        /// Writtable file was closed.
        FAN_CLOSE_WRITE;
        /// Unwrittable file was closed.
        FAN_CLOSE_NOWRITE;
        /// File was opened.
        FAN_OPEN;
        /// File was moved from X. Since Linux 5.1.
        FAN_MOVED_FROM;
        /// File was moved to Y. Since Linux 5.1.
        FAN_MOVED_TO;
        /// Subfile was created. Since Linux 5.1.
        FAN_CREATE;
        /// Subfile was deleted. Since Linux 5.1.
        FAN_DELETE;
        /// Self was deleted. Since Linux 5.1.
        FAN_DELETE_SELF;
        /// Self was moved. Since Linux 5.1.
        FAN_MOVE_SELF;
        /// File was opened for execution. Since Linux 5.0.
        FAN_OPEN_EXEC;

        /// Event queue overflowed.
        FAN_Q_OVERFLOW;
        /// Filesystem error. Since Linux 5.16.
        FAN_FS_ERROR;

        /// Permission to open file was requested.
        FAN_OPEN_PERM;
        /// Permission to access file was requested.
        FAN_ACCESS_PERM;
        /// Permission to open file for execution was requested. Since Linux
        /// 5.0.
        FAN_OPEN_EXEC_PERM;

        /// Interested in child events.
        FAN_EVENT_ON_CHILD;

        /// File was renamed. Since Linux 5.17.
        FAN_RENAME;

        /// Event occurred against dir.
        FAN_ONDIR;

        /// Combination of `FAN_CLOSE_WRITE` and `FAN_CLOSE_NOWRITE`.
        FAN_CLOSE;
        /// Combination of `FAN_MOVED_FROM` and `FAN_MOVED_TO`.
        FAN_MOVE;
    }
}

libc_bitflags! {
    /// Configuration options for [`fanotify_init`](fn.fanotify_init.html).
    pub struct InitFlags: libc::c_uint {
        /// Close-on-exec flag set on the file descriptor.
        FAN_CLOEXEC;
        /// Nonblocking flag set on the file descriptor.
        FAN_NONBLOCK;

        /// Receipt of events notifications.
        FAN_CLASS_NOTIF;
        /// Receipt of events for permission decisions, after they contain final
        /// data.
        FAN_CLASS_CONTENT;
        /// Receipt of events for permission decisions, before they contain
        /// final data.
        FAN_CLASS_PRE_CONTENT;

        /// Remove the limit of 16384 events for the event queue.
        FAN_UNLIMITED_QUEUE;
        /// Remove the limit of 8192 marks.
        FAN_UNLIMITED_MARKS;

        /// Make `FanotifyEvent::pid` return pidfd. Since Linux 5.15.
        FAN_REPORT_PIDFD;
        /// Make `FanotifyEvent::pid` return thread id. Since Linux 4.20.
        FAN_REPORT_TID;
    }
}

libc_bitflags! {
    /// File status flags for fanotify events file descriptors.
    pub struct EventFFlags: libc::c_uint {
        /// Read only access.
        O_RDONLY as libc::c_uint;
        /// Write only access.
        O_WRONLY as libc::c_uint;
        /// Read and write access.
        O_RDWR as libc::c_uint;
        /// Support for files exceeded 2 GB.
        O_LARGEFILE as libc::c_uint;
        /// Close-on-exec flag for the file descriptor. Since Linux 3.18.
        O_CLOEXEC as libc::c_uint;
        /// Append mode for the file descriptor.
        O_APPEND as libc::c_uint;
        /// Synchronized I/O data integrity completion.
        O_DSYNC as libc::c_uint;
        /// No file last access time update.
        O_NOATIME as libc::c_uint;
        /// Nonblocking mode for the file descriptor.
        O_NONBLOCK as libc::c_uint;
        /// Synchronized I/O file integrity completion.
        O_SYNC as libc::c_uint;
    }
}

impl TryFrom<OFlag> for EventFFlags {
    type Error = Errno;

    fn try_from(o_flag: OFlag) -> Result<Self> {
        EventFFlags::from_bits(o_flag.bits() as u32).ok_or(Errno::EINVAL)
    }
}

impl From<EventFFlags> for OFlag {
    fn from(event_f_flags: EventFFlags) -> Self {
        OFlag::from_bits_retain(event_f_flags.bits() as i32)
    }
}

libc_bitflags! {
    /// Configuration options for [`fanotify_mark`](fn.fanotify_mark.html).
    pub struct MarkFlags: libc::c_uint {
        /// Add the events to the marks.
        FAN_MARK_ADD;
        /// Remove the events to the marks.
        FAN_MARK_REMOVE;
        /// Don't follow symlinks, mark them.
        FAN_MARK_DONT_FOLLOW;
        /// Raise an error if filesystem to be marked is not a directory.
        FAN_MARK_ONLYDIR;
        /// Events added to or removed from the marks.
        FAN_MARK_IGNORED_MASK;
        /// Ignore mask shall survive modify events.
        FAN_MARK_IGNORED_SURV_MODIFY;
        /// Remove all marks.
        FAN_MARK_FLUSH;
        /// Do not pin inode object in the inode cache. Since Linux 5.19.
        FAN_MARK_EVICTABLE;
        /// Events added to or removed from the marks. Since Linux 6.0.
        FAN_MARK_IGNORE;

        /// Default flag.
        FAN_MARK_INODE;
        /// Mark the mount specified by pathname.
        FAN_MARK_MOUNT;
        /// Mark the filesystem specified by pathname. Since Linux 4.20.
        FAN_MARK_FILESYSTEM;

        /// Combination of `FAN_MARK_IGNORE` and `FAN_MARK_IGNORED_SURV_MODIFY`.
        FAN_MARK_IGNORE_SURV;
    }
}

/// Compile version number of fanotify API.
pub const FANOTIFY_METADATA_VERSION: u8 = libc::FANOTIFY_METADATA_VERSION;

/// Abstract over `libc::fanotify_event_metadata`, which represents an event
/// received via `Fanotify::read_events`.
// Is not Clone due to fd field, to avoid use-after-close scenarios.
#[derive(Debug, Eq, Hash, PartialEq)]
#[repr(transparent)]
#[allow(missing_copy_implementations)]
pub struct FanotifyEvent(libc::fanotify_event_metadata);

impl FanotifyEvent {
    /// Version number for the structure. It must be compared to
    /// `FANOTIFY_METADATA_VERSION` to verify compile version and runtime
    /// version does match. It can be done with the
    /// `FanotifyEvent::check_version` method.
    pub fn version(&self) -> u8 {
        self.0.vers
    }

    /// Checks that compile fanotify API version is equal to the version of the
    /// event.
    pub fn check_version(&self) -> bool {
        self.version() == FANOTIFY_METADATA_VERSION
    }

    /// Mask flags of the events.
    pub fn mask(&self) -> MaskFlags {
        MaskFlags::from_bits_truncate(self.0.mask)
    }

    /// The file descriptor of the event. If the value is `None` when reading
    /// from the fanotify group, this event is to notify that a group queue
    /// overflow occured.
    pub fn fd(&self) -> Option<BorrowedFd> {
        if self.0.fd == libc::FAN_NOFD {
            None
        } else {
            // SAFETY: self.0.fd will be opened for the lifetime of `Self`,
            // which is longer than the lifetime of the returned BorrowedFd, so
            // it is safe.
            Some(unsafe { BorrowedFd::borrow_raw(self.0.fd) })
        }
    }

    /// PID of the process that caused the event. TID in case flag
    /// `FAN_REPORT_TID` was set at group initialization.
    pub fn pid(&self) -> i32 {
        self.0.pid
    }
}

impl Drop for FanotifyEvent {
    fn drop(&mut self) {
        let e = close(self.0.fd);
        if !std::thread::panicking() && e == Err(Errno::EBADF) {
            panic!("Closing an invalid file descriptor!");
        };
    }
}

/// Abstraction over the structure to be sent to allow or deny a given event.
#[derive(Debug)]
#[repr(transparent)]
pub struct FanotifyResponse<'a> {
    inner: libc::fanotify_response,
    _borrowed_fd: PhantomData<BorrowedFd<'a>>,
}

impl<'a> FanotifyResponse<'a> {
    /// Create a new response.
    pub fn new(fd: BorrowedFd<'a>, response: Response) -> Self {
        Self {
            inner: libc::fanotify_response {
                fd: fd.as_raw_fd(),
                response: response.bits(),
            },
            _borrowed_fd: PhantomData,
        }
    }
}

libc_bitflags! {
    /// Response to be wrapped in `FanotifyResponse` and sent to the `Fanotify`
    /// group to allow or deny an event.
    pub struct Response: u32 {
        /// Allow the event.
        FAN_ALLOW;
        /// Deny the event.
        FAN_DENY;
    }
}

/// A fanotify group. This is also a file descriptor that can feed to other
/// interfaces consuming file descriptors.
#[derive(Debug)]
pub struct Fanotify {
    fd: OwnedFd,
}

impl Fanotify {
    /// Initialize a new fanotify group.
    ///
    /// Returns a Result containing a Fanotify instance.
    ///
    /// For more information, see [fanotify_init(2)](https://man7.org/linux/man-pages/man7/fanotify_init.2.html).
    pub fn init(
        flags: InitFlags,
        event_f_flags: EventFFlags,
    ) -> Result<Fanotify> {
        let res = Errno::result(unsafe {
            libc::fanotify_init(flags.bits(), event_f_flags.bits())
        });
        res.map(|fd| Fanotify {
            fd: unsafe { OwnedFd::from_raw_fd(fd) },
        })
    }

    /// Add, remove, or modify an fanotify mark on a filesystem object.
    /// If `dirfd` is `None`, `AT_FDCWD` is used.
    ///
    /// Returns a Result containing either `()` on success or errno otherwise.
    ///
    /// For more information, see [fanotify_mark(2)](https://man7.org/linux/man-pages/man7/fanotify_mark.2.html).
    pub fn mark<P: ?Sized + NixPath>(
        &self,
        flags: MarkFlags,
        mask: MaskFlags,
        dirfd: Option<RawFd>,
        path: Option<&P>,
    ) -> Result<()> {
        fn with_opt_nix_path<P, T, F>(p: Option<&P>, f: F) -> Result<T>
        where
            P: ?Sized + NixPath,
            F: FnOnce(*const libc::c_char) -> T,
        {
            match p {
                Some(path) => path.with_nix_path(|p_str| f(p_str.as_ptr())),
                None => Ok(f(std::ptr::null())),
            }
        }

        let res = with_opt_nix_path(path, |p| unsafe {
            libc::fanotify_mark(
                self.fd.as_raw_fd(),
                flags.bits(),
                mask.bits(),
                at_rawfd(dirfd),
                p,
            )
        })?;

        Errno::result(res).map(|_| ())
    }

    /// Read incoming events from the fanotify group.
    ///
    /// Returns a Result containing either a `Vec` of events on success or errno
    /// otherwise.
    ///
    /// # Errors
    ///
    /// Possible errors can be those that are explicitly listed in
    /// [fanotify(2)](https://man7.org/linux/man-pages/man7/fanotify.2.html) in
    /// addition to the possible errors caused by `read` call.
    /// In particular, `EAGAIN` is returned when no event is available on a
    /// group that has been initialized with the flag `InitFlags::FAN_NONBLOCK`,
    /// thus making this method nonblocking.
    pub fn read_events(&self) -> Result<Vec<FanotifyEvent>> {
        let metadata_size = size_of::<libc::fanotify_event_metadata>();
        const BUFSIZ: usize = 4096;
        let mut buffer = [0u8; BUFSIZ];
        let mut events = Vec::new();
        let mut offset = 0;

        let nread = read(self.fd.as_raw_fd(), &mut buffer)?;

        while (nread - offset) >= metadata_size {
            let metadata = unsafe {
                let mut metadata =
                    MaybeUninit::<libc::fanotify_event_metadata>::uninit();
                ptr::copy_nonoverlapping(
                    buffer.as_ptr().add(offset),
                    metadata.as_mut_ptr().cast(),
                    (BUFSIZ - offset).min(metadata_size),
                );
                metadata.assume_init()
            };

            events.push(FanotifyEvent(metadata));
            offset += metadata.event_len as usize;
        }

        Ok(events)
    }

    /// Write an event response on the fanotify group.
    ///
    /// Returns a Result containing either `()` on success or errno otherwise.
    ///
    /// # Errors
    ///
    /// Possible errors can be those that are explicitly listed in
    /// [fanotify(2)](https://man7.org/linux/man-pages/man7/fanotify.2.html) in
    /// addition to the possible errors caused by `write` call.
    /// In particular, `EAGAIN` or `EWOULDBLOCK` is returned when no event is
    /// available on a group that has been initialized with the flag
    /// `InitFlags::FAN_NONBLOCK`, thus making this method nonblocking.
    pub fn write_response(&self, response: FanotifyResponse) -> Result<()> {
        write(self.fd.as_fd(), unsafe {
            std::slice::from_raw_parts(
                (&response.inner as *const libc::fanotify_response).cast(),
                size_of::<libc::fanotify_response>(),
            )
        })?;
        Ok(())
    }
}

impl FromRawFd for Fanotify {
    unsafe fn from_raw_fd(fd: RawFd) -> Self {
        Fanotify {
            fd: unsafe { OwnedFd::from_raw_fd(fd) },
        }
    }
}

impl AsFd for Fanotify {
    fn as_fd(&'_ self) -> BorrowedFd<'_> {
        self.fd.as_fd()
    }
}
