//! Provides facilities for file locks on unix and windows

use crate::{Error, Path, PathBuf};
use std::{fs, time::Duration};

#[cfg_attr(unix, path = "flock/unix.rs")]
#[cfg_attr(windows, path = "flock/windows.rs")]
mod sys;

/// An error pertaining to a failed file lock
#[derive(Debug, thiserror::Error)]
#[error("failed to obtain lock file '{path}'")]
pub struct FileLockError {
    /// The path of the file lock
    pub path: PathBuf,
    /// The underlying failure reason
    pub source: LockError,
}

/// Errors that can occur when attempting to acquire a [`FileLock`]
#[derive(Debug, thiserror::Error)]
pub enum LockError {
    /// An I/O error occurred attempting to open the lock file
    #[error(transparent)]
    Open(std::io::Error),
    /// Exclusive locks cannot be take on read-only file systems
    #[error("attempted to take an exclusive lock on a read-only path")]
    Readonly,
    /// Failed to create parents directories to lock file
    #[error("failed to create parent directories for lock path")]
    CreateDir(std::io::Error),
    /// Locking is not supported if the lock file is on an NFS, though note this
    /// is a bit more nuanced as NFSv4 _does_ support file locking, but is out
    /// of scope, at least for now
    #[error("NFS do not support locking")]
    Nfs,
    /// This could happen on eg. _extremely_ old and outdated OSes or some filesystems
    /// and is only present for completeness
    #[error("locking is not supported on the filesystem and/or in the kernel")]
    NotSupported,
    /// An I/O error occurred attempting to un/lock the file
    #[error("failed to acquire or release file lock")]
    Lock(std::io::Error),
    /// The lock could not be acquired within the caller provided timeout
    #[error("failed to acquire lock within the specified duration")]
    TimedOut,
    /// The lock is currently held by another
    #[error("the lock is currently held by another")]
    Contested,
}

/// Provides options for creating a [`FileLock`]
pub struct LockOptions<'pb> {
    path: std::borrow::Cow<'pb, Path>,
    exclusive: bool,
    shared_fallback: bool,
}

impl<'pb> LockOptions<'pb> {
    /// Creates a new [`Self`] for the specified path
    #[inline]
    pub fn new(path: &'pb Path) -> Self {
        Self {
            path: path.into(),
            exclusive: false,
            shared_fallback: false,
        }
    }

    /// Creates a new [`Self`] for locking cargo's global package lock
    ///
    /// If specified, the path is used as the root, otherwise it is rooted at
    /// the path determined by `$CARGO_HOME`
    #[inline]
    pub fn cargo_package_lock(root: Option<PathBuf>) -> Result<Self, Error> {
        let mut path = if let Some(root) = root {
            root
        } else {
            crate::utils::cargo_home()?
        };
        path.push(".package-cache");

        Ok(Self {
            path: path.into(),
            exclusive: true,
            shared_fallback: false,
        })
    }

    /// Will attempt to acquire a shared lock rather than an exclusive one
    #[inline]
    pub fn shared(mut self) -> Self {
        self.exclusive = false;
        self
    }

    /// Will attempt to acquire an exclusive lock, which can optionally fallback
    /// to a shared lock if the lock file is for a read only filesystem
    #[inline]
    pub fn exclusive(mut self, shared_fallback: bool) -> Self {
        self.exclusive = true;
        self.shared_fallback = shared_fallback;
        self
    }

    /// Attempts to acquire a lock, but fails immediately if the lock is currently
    /// held
    #[inline]
    pub fn try_lock(&self) -> Result<FileLock, Error> {
        self.open_and_lock(Option::<fn(&Path) -> Option<Duration>>::None)
    }

    /// Attempts to acquire a lock, waiting if the lock is currently held.
    ///
    /// Unlike [`Self::try_lock`], if the lock is currently held, the specified
    /// callback is called to inform the caller that a wait is about to
    /// be performed, then waits for the amount of time specified by the return
    /// of the callback, or infinitely in the case of `None`.
    #[inline]
    pub fn lock(&self, wait: impl Fn(&Path) -> Option<Duration>) -> Result<FileLock, Error> {
        self.open_and_lock(Some(wait))
    }

    fn open(&self, opts: &fs::OpenOptions) -> Result<fs::File, FileLockError> {
        opts.open(self.path.as_std_path()).or_else(|err| {
            if err.kind() == std::io::ErrorKind::NotFound && self.exclusive {
                fs::create_dir_all(self.path.parent().unwrap()).map_err(|e| FileLockError {
                    path: self.path.parent().unwrap().to_owned(),
                    source: LockError::CreateDir(e),
                })?;
                self.open(opts)
            } else {
                // Note we just use the 30 EROFS constant here, which won't work on WASI, Haiku, or some other
                // niche targets, but none of them are intended targets for this crate, but can be fixed later
                // if someone actually uses them
                let source = if err.kind() == std::io::ErrorKind::PermissionDenied
                    || cfg!(unix) && err.raw_os_error() == Some(30 /* EROFS */)
                {
                    LockError::Readonly
                } else {
                    LockError::Open(err)
                };

                Err(FileLockError {
                    path: self.path.as_ref().to_owned(),
                    source,
                })
            }
        })
    }

    fn open_and_lock(
        &self,
        wait: Option<impl Fn(&Path) -> Option<Duration>>,
    ) -> Result<FileLock, Error> {
        let (state, file) = if self.exclusive {
            match self.open(&sys::open_opts(true)) {
                Ok(file) => (LockState::Exclusive, file),
                Err(err) => {
                    // If the user requested it, check if the error is due to a read only error,
                    // and if so, fallback to a shared lock instead of an exclusive lock, just
                    // as cargo does
                    //
                    // https://github.com/rust-lang/cargo/blob/0b6cc3c75f1813df857fb54421edf7f8fee548e3/src/cargo/util/config/mod.rs#L1907-L1935
                    if self.shared_fallback && matches!(err.source, LockError::Readonly) {
                        (LockState::Shared, self.open(&sys::open_opts(false))?)
                    } else {
                        return Err(err.into());
                    }
                }
            }
        } else {
            (LockState::Shared, self.open(&sys::open_opts(false))?)
        };

        self.do_lock(state, &file, wait)
            .map_err(|source| FileLockError {
                path: self.path.as_ref().to_owned(),
                source,
            })?;

        Ok(FileLock {
            file: Some(file),
            state,
        })
    }

    fn do_lock(
        &self,
        state: LockState,
        file: &fs::File,
        wait: Option<impl Fn(&Path) -> Option<std::time::Duration>>,
    ) -> Result<(), LockError> {
        #[cfg(all(target_os = "linux", not(target_env = "musl")))]
        fn is_on_nfs_mount(path: &crate::Path) -> bool {
            use std::os::unix::prelude::*;

            let path = match std::ffi::CString::new(path.as_os_str().as_bytes()) {
                Ok(path) => path,
                Err(_) => return false,
            };

            #[allow(unsafe_code)]
            unsafe {
                let mut buf: libc::statfs = std::mem::zeroed();
                let r = libc::statfs(path.as_ptr(), &mut buf);

                r == 0 && buf.f_type as u32 == libc::NFS_SUPER_MAGIC as u32
            }
        }

        #[cfg(any(not(target_os = "linux"), target_env = "musl"))]
        fn is_on_nfs_mount(_path: &crate::Path) -> bool {
            false
        }

        // File locking on Unix is currently implemented via `flock`, which is known
        // to be broken on NFS. We could in theory just ignore errors that happen on
        // NFS, but apparently the failure mode [1] for `flock` on NFS is **blocking
        // forever**, even if the "non-blocking" flag is passed!
        //
        // As a result, we just skip all file locks entirely on NFS mounts. That
        // should avoid calling any `flock` functions at all, and it wouldn't work
        // there anyway.
        //
        // [1]: https://github.com/rust-lang/cargo/issues/2615
        if is_on_nfs_mount(&self.path) {
            return Err(LockError::Nfs);
        }

        match sys::try_lock(file, state) {
            Ok(()) => return Ok(()),

            // In addition to ignoring NFS which is commonly not working we also
            // just ignore locking on filesystems that look like they don't
            // implement file locking.
            Err(e) if sys::is_unsupported(&e) => return Err(LockError::NotSupported),

            Err(e) => {
                if !sys::is_contended(&e) {
                    return Err(LockError::Lock(e));
                }
            }
        }

        // Signal to the caller that we are about to enter a blocking operation
        // and whether they want to assign a timeout to it
        if let Some(wait) = wait {
            let timeout = wait(&self.path);

            sys::lock(file, state, timeout).map_err(|e| {
                if sys::is_timed_out(&e) {
                    LockError::TimedOut
                } else {
                    LockError::Lock(e)
                }
            })
        } else {
            Err(LockError::Contested)
        }
    }
}

#[derive(PartialEq, Copy, Clone, Debug)]
enum LockState {
    Exclusive,
    Shared,
    Unlocked,
}

/// A currently held file lock.
///
/// The lock is released when this is dropped, or the program exits for any reason,
/// including `SIGKILL` or power loss
pub struct FileLock {
    file: Option<std::fs::File>,
    state: LockState,
}

impl FileLock {
    /// Creates a [`Self`] in an unlocked state.
    ///
    /// This allows for easy testing or use in situations where you don't care
    /// about file locking, or have other ways to ensure something is uncontested
    pub fn unlocked() -> Self {
        Self {
            file: None,
            state: LockState::Unlocked,
        }
    }
}

impl Drop for FileLock {
    fn drop(&mut self) {
        if self.state != LockState::Unlocked {
            if let Some(f) = self.file.take() {
                let _ = sys::unlock(&f);
            }
        }
    }
}
