//! `redox-users` is designed to be a small, low-ish level interface
//! to system user and group information, as well as user password
//! authentication. It is OS-specific and will break horribly on platforms
//! that are not [Redox-OS](https://redox-os.org).
//!
//! # Permissions
//! Because this is a system level tool dealing with password
//! authentication, programs are often required to run with
//! escalated priveleges. The implementation of the crate is
//! privelege unaware. The only privelege requirements are those
//! laid down by the system administrator over these files:
//! - `/etc/group`
//!   - Read: Required to access group information
//!   - Write: Required to change group information
//! - `/etc/passwd`
//!   - Read: Required to access user information
//!   - Write: Required to change user information
//! - `/etc/shadow`
//!   - Read: Required to authenticate users
//!   - Write: Required to set user passwords
//!
//! # Reimplementation
//! This crate is designed to be as small as possible without
//! sacrificing critical functionality. The idea is that a small
//! enough redox-users will allow easy re-implementation based on
//! the same flexible API. This would allow more complicated authentication
//! schemes for redox in future without breakage of existing
//! software.

use std::convert::From;
use std::fmt::Debug;
use std::fs::{File, OpenOptions};
use std::io::{Read, Seek, SeekFrom, Write};
#[cfg(target_os = "redox")]
use std::os::unix::fs::OpenOptionsExt;
#[cfg(not(target_os = "redox"))]
use std::os::unix::io::AsRawFd;
use std::os::unix::process::CommandExt;
use std::path::{Path, PathBuf};
use std::process::Command;
use std::slice::{Iter, IterMut};
#[cfg(not(test))]
#[cfg(feature = "auth")]
use std::thread;
use std::time::Duration;

use thiserror::Error;
#[cfg(feature = "auth")]
use zeroize::Zeroize;

//#[cfg(not(target_os = "redox"))]
//use nix::fcntl::{flock, FlockArg};

#[cfg(target_os = "redox")]
use syscall::flag::{O_EXLOCK, O_SHLOCK};

const PASSWD_FILE: &'static str = "/etc/passwd";
const GROUP_FILE: &'static str = "/etc/group";
#[cfg(feature = "auth")]
const SHADOW_FILE: &'static str = "/etc/shadow";

#[cfg(target_os = "redox")]
const DEFAULT_SCHEME: &'static str = "file:";
#[cfg(not(target_os = "redox"))]
const DEFAULT_SCHEME: &'static str = "";

const MIN_ID: usize = 1000;
const MAX_ID: usize = 6000;
const DEFAULT_TIMEOUT: u64 = 3;

const USERNAME_LEN_MIN: usize = 3;
const USERNAME_LEN_MAX: usize = 32;

/// Errors that might happen while using this crate
#[derive(Debug, Error)]
#[non_exhaustive]
pub enum Error {
    #[error("os error: {reason}")]
    Os { reason: &'static str },

    #[error(transparent)]
    Io(#[from] std::io::Error),

    #[error("failed to generate seed: {0}")]
    Getrandom(#[from] getrandom::Error),

    #[cfg(feature = "auth")]
    #[error("")]
    Argon(#[from] argon2::Error),

    #[error("parse error line {line}: {reason}")]
    Parsing { reason: String, line: usize },

    #[error(transparent)]
    ParseInt(#[from] std::num::ParseIntError),

    #[error("user not found")]
    UserNotFound,

    #[error("group not found")]
    GroupNotFound,

    #[error("user already exists")]
    UserAlreadyExists,

    #[error("group already exists")]
    GroupAlreadyExists,

    #[error("invalid name '{name}'")]
    InvalidName { name: String },

    /// Used for invalid string field values of [`User`]
    #[error("invalid entry element '{data}'")]
    InvalidData { data: String },
}

#[inline]
fn parse_error(line: usize, reason: &str) -> Error {
    Error::Parsing {
        reason: reason.into(),
        line,
    }
}

impl From<syscall::Error> for Error {
    fn from(syscall_error: syscall::Error) -> Error {
        Error::Os { reason: syscall_error.text() }
    }
}

#[derive(Clone, Copy, Debug)]
enum Lock {
    Shared,
    Exclusive,
}

impl Lock {
    fn can_write(&self) -> bool {
        match self {
            Lock::Shared => false,
            Lock::Exclusive => true,
        }
    }

    #[cfg(target_os = "redox")]
    fn as_olock(self) -> i32 {
        (match self {
            Lock::Shared => O_SHLOCK,
            Lock::Exclusive => O_EXLOCK,
        }) as i32
    }

    /*#[cfg(not(target_os = "redox"))]
    fn as_flock(self) -> FlockArg {
        match self {
            Lock::Shared => FlockArg::LockShared,
            Lock::Exclusive => FlockArg::LockExclusive,
        }
    }*/
}

/// Naive semi-cross platform file locking (need to support linux for tests).
#[allow(dead_code)]
fn locked_file(file: impl AsRef<Path>, lock: Lock) -> Result<File, Error> {
    #[cfg(test)]
    println!("Open file: {}", file.as_ref().display());

    #[cfg(target_os = "redox")]
    {
        Ok(OpenOptions::new()
            .read(true)
            .write(lock.can_write())
            .custom_flags(lock.as_olock())
            .open(file)?)
    }
    #[cfg(not(target_os = "redox"))]
    #[cfg_attr(rustfmt, rustfmt_skip)]
    {
        let file = OpenOptions::new()
            .read(true)
            .write(lock.can_write())
            .open(file)?;
        let fd = file.as_raw_fd();
        eprintln!("Fd: {}", fd);
        //flock(fd, lock.as_flock())?;
        Ok(file)
    }
}

/// Reset a file for rewriting (user/group dbs must be erased before write-out)
fn reset_file(fd: &mut File) -> Result<(), Error> {
    fd.set_len(0)?;
    fd.seek(SeekFrom::Start(0))?;
    Ok(())
}

/// Is a string safe to write to `/etc/group` or `/etc/passwd`?
fn is_safe_string(s: &str) -> bool {
    !s.contains(';')
}

const PORTABLE_FILE_NAME_CHARS: &str =
    "0123456789._-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";

/// This function is used by [`UserBuilder`] and [`GroupBuilder`] to determine
/// if a name for a user/group is valid. It is provided for convenience.
///
/// Usernames must match the [POSIX standard
/// for usernames](https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap03.html#tag_03_437)
/// . The "portable filename character set" is defined as `A-Z`, `a-z`, `0-9`,
/// and `._-` (see [here](https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap03.html#tag_03_282)).
///
/// Usernames may not be more than 32 or less than 3 characters in length.
pub fn is_valid_name(name: &str) -> bool {
    if name.len() < USERNAME_LEN_MIN || name.len() > USERNAME_LEN_MAX {
        false
    } else if let Some(first) = name.chars().next() {
        first != '-' &&
            name.chars().all(|c| {
                PORTABLE_FILE_NAME_CHARS.contains(c)
            })
    } else {
        false
    }
}

/// Marker types for [`User`] and [`AllUsers`].
pub mod auth {
    #[cfg(feature = "auth")]
    use std::fmt;

    #[cfg(feature = "auth")]
    use zeroize::Zeroize;

    #[cfg(feature = "auth")]
    use crate::Error;

    /// Marker type indicating that a `User` only has access to world-readable
    /// user information, and cannot authenticate.
    #[derive(Debug, Default)]
    pub struct Basic {}

    /// Marker type indicating that a `User` has access to all user
    /// information, including password hashes.
    #[cfg(feature = "auth")]
    #[derive(Default, Zeroize)]
    #[zeroize(drop)]
    pub struct Full {
        pub(crate) hash: String,
    }

    #[cfg(feature = "auth")]
    impl Full {
        pub(crate) fn empty() -> Full {
            Full { hash: "".into() }
        }

        pub(crate) fn is_empty(&self) -> bool {
            &self.hash == ""
        }

        pub(crate) fn unset() -> Full {
            Full { hash: "!".into() }
        }

        pub(crate) fn is_unset(&self) -> bool {
            &self.hash == "!"
        }

        pub(crate) fn passwd(pw: &str) -> Result<Full, Error> {
            Ok(if pw != "" {
                let mut buf = [0u8; 8];
                getrandom::getrandom(&mut buf)?;
                let mut salt = format!("{:X}", u64::from_ne_bytes(buf));

                let config = argon2::Config::default();
                let hash: String = argon2::hash_encoded(
                    pw.as_bytes(),
                    salt.as_bytes(),
                    &config
                )?;

                buf.zeroize();
                salt.zeroize();
                Full { hash } // note that move == shallow copy in Rust
            } else {
                Full::empty()
            })
        }

        pub(crate) fn verify(&self, pw: &str) -> bool {
            match self.hash.as_str() {
                "" => pw == "",
                "!" => false,
                //TODO: When does this panic? Should this function return
                // Result? Or does it need to simply fail to verify if
                // verify_encoded() fails?
                hash => argon2::verify_encoded(&hash, pw.as_bytes())
                    .expect("failed to verify hash"),
            }
        }
    }

    #[cfg(feature = "auth")]
    impl fmt::Debug for Full {
        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
            f.debug_struct("Full")
                .finish()
        }
    }
}

/// A builder pattern for adding [`User`]s to [`AllUsers`]. Fields are verified
/// when the group is built via [`AllUsers::add_user`]. See the documentation
/// of that function for default values.
///
/// Note that this builder is not available when the `auth` feature of the
/// crate is disabled.
///
/// # Example
/// ```no_run
/// # use redox_users::{AllGroups, Config, GroupBuilder, UserBuilder};
/// let mut allgs = AllGroups::new(Config::default()).unwrap();
///
/// let g = GroupBuilder::new("foobar")
///     .user("foobar");
/// let foobar_g = allgs.add_group(g).unwrap();
///
/// let u = UserBuilder::new("foobar")
///     .gid(foobar_g.gid)
///     .name("Foo Bar")
///     // Note that this directory will not be created
///     .home("file:/home/foobar");
/// ```
#[cfg(feature = "auth")]
pub struct UserBuilder {
    user: String,
    uid: Option<usize>,
    gid: Option<usize>,
    name: Option<String>,
    home: Option<String>,
    shell: Option<String>,
}

#[cfg(feature = "auth")]
impl UserBuilder {
    /// Create a new `UserBuilder` with the login name for the new user.
    pub fn new(user: impl AsRef<str>) -> UserBuilder {
        UserBuilder {
            user: user.as_ref().to_string(),
            uid: None,
            gid: None,
            name: None,
            home: None,
            shell: None,
        }
    }

    /// Set the user id for this user.
    pub fn uid(mut self, uid: usize) -> UserBuilder {
        self.uid = Some(uid);
        self
    }

    /// Set the primary group id for this user.
    pub fn gid(mut self, gid: usize) -> UserBuilder {
        self.gid = Some(gid);
        self
    }

    /// Set the GECOS field for this user.
    pub fn name(mut self, name: impl AsRef<str>) -> UserBuilder {
        self.name = Some(name.as_ref().to_string());
        self
    }

    /// Set the home directory for this user.
    pub fn home(mut self, home: impl AsRef<str>) -> UserBuilder {
        self.home = Some(home.as_ref().to_string());
        self
    }

    /// Set the login shell for this user.
    pub fn shell(mut self, shell: impl AsRef<str>) -> UserBuilder {
        self.shell = Some(shell.as_ref().to_string());
        self
    }
}

/// A struct representing a Redox user.
/// Currently maps to an entry in the `/etc/passwd` file.
///
/// `A` should be a type from [`crate::auth`].
///
/// # Unset vs. Blank Passwords
/// A note on unset passwords vs. blank passwords. A blank password
/// is a hash field that is completely blank (aka, `""`). According
/// to this crate, successful login is only allowed if the input
/// password is blank as well.
///
/// An unset password is one whose hash is not empty (`""`), but
/// also not a valid serialized argon2rs hashing session. This
/// hash always returns `false` upon attempted verification. The
/// most commonly used hash for an unset password is `"!"`, but
/// this crate makes no distinction. The most common way to unset
/// the password is to use [`User::unset_passwd`].
#[derive(Debug)]
pub struct User<A> {
    /// Username (login name)
    pub user: String,
    /// User id
    pub uid: usize,
    /// Group id
    pub gid: usize,
    /// Real name (human readable, can contain spaces)
    pub name: String,
    /// Home directory path
    pub home: String,
    /// Shell path
    pub shell: String,

    // Failed login delay duration
    auth_delay: Duration,

    #[allow(dead_code)]
    auth: A,
}

impl<A: Default> User<A> {
    /// Get a Command to run the user's default shell (see [`User::login_cmd`]
    /// for more docs).
    pub fn shell_cmd(&self) -> Command { self.login_cmd(&self.shell) }

    /// Provide a login command for the user, which is any entry point for
    /// starting a user's session, whether a shell (use [`User::shell_cmd`]
    /// instead) or a graphical init.
    ///
    /// The `Command` will use the user's `uid` and `gid`, its `current_dir`
    /// will be set to the user's home directory, and the follwing enviroment
    /// variables will be populated:
    ///
    ///    - `USER` set to the user's `user` field.
    ///    - `UID` set to the user's `uid` field.
    ///    - `GROUPS` set the user's `gid` field.
    ///    - `HOME` set to the user's `home` field.
    ///    - `SHELL` set to the user's `shell` field.
    pub fn login_cmd<T>(&self, cmd: T) -> Command
        where T: std::convert::AsRef<std::ffi::OsStr> + AsRef<str>
    {
        let mut command = Command::new(cmd);
        command
            .uid(self.uid as u32)
            .gid(self.gid as u32)
            .current_dir(&self.home)
            .env("USER", &self.user)
            .env("UID", format!("{}", self.uid))
            .env("GROUPS", format!("{}", self.gid))
            .env("HOME", &self.home)
            .env("SHELL", &self.shell);
        command
    }

    fn from_passwd_entry(s: &str, line: usize) -> Result<User<A>, Error> {
        let mut parts = s.split(';');

        let user = parts
            .next()
            .ok_or(parse_error(line, "expected user"))?;
        let uid = parts
            .next()
            .ok_or(parse_error(line, "expected uid"))?
            .parse::<usize>()?;
        let gid = parts
            .next()
            .ok_or(parse_error(line, "expected uid"))?
            .parse::<usize>()?;
        let name = parts
            .next()
            .ok_or(parse_error(line, "expected real name"))?;
        let home = parts
            .next()
            .ok_or(parse_error(line, "expected home dir path"))?;
        let shell = parts
            .next()
            .ok_or(parse_error(line, "expected shell path"))?;

        Ok(User::<A> {
            user: user.into(),
            uid,
            gid,
            name: name.into(),
            home: home.into(),
            shell: shell.into(),
            auth: A::default(),
            auth_delay: Duration::default(),
        })
    }
}

#[cfg(feature = "auth")]
impl User<auth::Full> {
    /// Set the password for a user. Make **sure** that `password`
    /// is actually what the user wants as their password (this doesn't).
    ///
    /// To set the password blank, pass `""` as `password`.
    ///
    /// Note that `password` is taken as a reference, so it is up to the caller
    /// to properly zero sensitive memory (see `zeroize` on crates.io).
    pub fn set_passwd(&mut self, password: impl AsRef<str>) -> Result<(), Error> {
        self.auth = auth::Full::passwd(password.as_ref())?;
        Ok(())
    }

    /// Unset the password ([`User::verify_passwd`] always returns `false`).
    pub fn unset_passwd(&mut self) {
        self.auth = auth::Full::unset();
    }

    /// Verify the password. If the hash is empty, this only returns `true` if
    /// `password` is also empty.
    ///
    /// Note that this is a blocking operation if the password is incorrect.
    /// See [`Config::auth_delay`] to set the wait time. Default is 3 seconds.
    ///
    /// Note that `password` is taken as a reference, so it is up to the caller
    /// to properly zero sensitive memory (see `zeroize` on crates.io).
    pub fn verify_passwd(&self, password: impl AsRef<str>) -> bool {
        let verified = self.auth.verify(password.as_ref());
        if !verified {
            #[cfg(not(test))] // Make tests run faster
            thread::sleep(self.auth_delay);
        }
        verified
    }

    /// Determine if the hash for the password is blank ([`User::verify_passwd`]
    /// returns `true` *only* when the password is blank).
    pub fn is_passwd_blank(&self) -> bool {
        self.auth.is_empty()
    }

    /// Determine if the hash for the password is unset
    /// ([`User::verify_passwd`] returns `false` regardless of input).
    pub fn is_passwd_unset(&self) -> bool {
        self.auth.is_unset()
    }

    /// Format this user as an entry in `/etc/passwd`.
    fn passwd_entry(&self) -> Result<String, Error> {
        if !is_safe_string(&self.user) {
            Err(Error::InvalidName { name: self.user.to_string() })
        } else if !is_safe_string(&self.name) {
            Err(Error::InvalidData { data: self.name.to_string() })
        } else if !is_safe_string(&self.home) {
            Err(Error::InvalidData { data: self.home.to_string() })
        } else if !is_safe_string(&self.shell) {
            Err(Error::InvalidData { data: self.shell.to_string() })
        } else {
            #[cfg_attr(rustfmt, rustfmt_skip)]
            Ok(format!("{};{};{};{};{};{}\n",
                self.user, self.uid, self.gid, self.name, self.home, self.shell
            ))
        }
    }

    fn shadow_entry(&self) -> Result<String, Error> {
        if !is_safe_string(&self.user) {
            Err(Error::InvalidName { name: self.user.to_string() })
        } else {
            Ok(format!("{};{}\n", self.user, self.auth.hash))
        }
    }
}

impl<A> Name for User<A> {
    fn name(&self) -> &str {
        &self.user
    }
}

impl<A> Id for User<A> {
    fn id(&self) -> usize {
        self.uid
    }
}

/// A builder pattern for adding [`Group`]s to [`AllGroups`]. Fields are
/// verified when the `Group` is built, via [`AllGroups::add_group`].
///
/// # Example
/// ```
/// # use redox_users::GroupBuilder;
/// // When added, this group will use the first available group id
/// let mygroup = GroupBuilder::new("group_name");
///
/// // A little more stuff:
/// let other = GroupBuilder::new("special")
///     .gid(9055)
///     .user("some_username");
/// ```
pub struct GroupBuilder {
    // Group name
    group: String,

    gid: Option<usize>,

    users: Vec<String>,
}

impl GroupBuilder {
    /// Create a new `GroupBuilder` with the given group name.
    pub fn new(group: impl AsRef<str>) -> GroupBuilder {
        GroupBuilder {
            group: group.as_ref().to_string(),
            gid: None,
            users: vec![],
        }
    }

    /// Set the group id of this group.
    pub fn gid(mut self, gid: usize) -> GroupBuilder {
        self.gid = Some(gid);
        self
    }

    /// Add a user to this group. Call this function multiple times to add more
    /// users.
    pub fn user(mut self, user: impl AsRef<str>) -> GroupBuilder {
        self.users.push(user.as_ref().to_string());
        self
    }
}

/// A struct representing a Redox user group.
/// Currently maps to an `/etc/group` file entry.
#[derive(Debug)]
pub struct Group {
    /// Group name
    pub group: String,
    /// Unique group id
    pub gid: usize,
    /// Group members' usernames
    pub users: Vec<String>,
}

impl Group {
    fn from_group_entry(s: &str, line: usize) -> Result<Group, Error> {
        let mut parts = s.trim()
            .split(';');

        let group = parts
            .next()
            .ok_or(parse_error(line, "expected group"))?;
        let gid = parts
            .next()
            .ok_or(parse_error(line, "expected gid"))?
            .parse::<usize>()?;
        let users_str = parts.next()
            .unwrap_or("");
        let users = users_str.split(',')
            .filter_map(|u| if u == "" {
                None
            } else {
                Some(u.into())
            })
            .collect();

        Ok(Group {
            group: group.into(),
            gid,
            users,
        })
    }

    fn group_entry(&self) -> Result<String, Error> {
        if !is_safe_string(&self.group) {
            Err(Error::InvalidName { name: self.group.to_string() })
        } else {
            for username in self.users.iter() {
                if !is_safe_string(&username) {
                    return Err(Error::InvalidData { data: username.to_string() });
                }
            }

            #[cfg_attr(rustfmt, rustfmt_skip)]
            Ok(format!("{};{};{}\n",
                self.group,
                self.gid,
                self.users.join(",").trim_matches(',')
            ))
        }
    }
}

impl Name for Group {
    fn name(&self) -> &str {
        &self.group
    }
}

impl Id for Group {
    fn id(&self) -> usize {
        self.gid
    }
}

/// Gets the current process effective user ID.
///
/// This function issues the `geteuid` system call returning the process effective
/// user id.
///
/// # Examples
///
/// Basic usage:
///
/// ```no_run
/// # use redox_users::get_euid;
/// let euid = get_euid().unwrap();
/// ```
pub fn get_euid() -> Result<usize, Error> {
    syscall::geteuid()
        .map_err(From::from)
}

/// Gets the current process real user ID.
///
/// This function issues the `getuid` system call returning the process real
/// user id.
///
/// # Examples
///
/// Basic usage:
///
/// ```no_run
/// # use redox_users::get_uid;
/// let uid = get_uid().unwrap();
/// ```
pub fn get_uid() -> Result<usize, Error> {
    syscall::getuid()
        .map_err(From::from)
}

/// Gets the current process effective group ID.
///
/// This function issues the `getegid` system call returning the process effective
/// group id.
///
/// # Examples
///
/// Basic usage:
///
/// ```no_run
/// # use redox_users::get_egid;
/// let egid = get_egid().unwrap();
/// ```
pub fn get_egid() -> Result<usize, Error> {
    syscall::getegid()
        .map_err(From::from)
}

/// Gets the current process real group ID.
///
/// This function issues the `getegid` system call returning the process real
/// group id.
///
/// # Examples
///
/// Basic usage:
///
/// ```no_run
/// # use redox_users::get_gid;
/// let gid = get_gid().unwrap();
/// ```
pub fn get_gid() -> Result<usize, Error> {
    syscall::getgid()
        .map_err(From::from)
}

/// A generic configuration that allows fine control of an [`AllUsers`] or
/// [`AllGroups`].
///
/// `auth_delay` is not used by [`AllGroups`]
///
/// In most situations, [`Config::default`](struct.Config.html#impl-Default)
/// will work just fine. The other fields are for finer control if it is
/// required.
///
/// # Example
/// ```
/// # use redox_users::Config;
/// use std::time::Duration;
///
/// let cfg = Config::default()
///     .min_id(500)
///     .max_id(1000)
///     .auth_delay(Duration::from_secs(5));
/// ```
#[derive(Clone, Debug)]
pub struct Config {
    scheme: String,
    auth_delay: Duration,
    min_id: usize,
    max_id: usize,
    lock: Lock,
}

impl Config {
    /// Set the delay for a failed authentication. Default is 3 seconds.
    pub fn auth_delay(mut self, delay: Duration) -> Config {
        self.auth_delay = delay;
        self
    }

    /// Set the smallest ID possible to use when finding an unused ID.
    pub fn min_id(mut self, id: usize) -> Config {
        self.min_id = id;
        self
    }

    /// Set the largest possible ID to use when finding an unused ID.
    pub fn max_id(mut self, id: usize) -> Config {
        self.max_id = id;
        self
    }

    /// Set the scheme relative to which the [`AllUsers`] or [`AllGroups`]
    /// should be looking for its data files. This is a compromise between
    /// exposing implementation details and providing fine enough
    /// control over the behavior of this API.
    pub fn scheme(mut self, scheme: String) -> Config {
        self.scheme = scheme;
        self
    }

    /// Allow writes to group, passwd, and shadow files
    pub fn writeable(mut self, writeable: bool) -> Config {
        self.lock = if writeable {
            Lock::Exclusive
        } else {
            Lock::Shared
        };
        self
    }

    // Prepend a path with the scheme in this Config
    fn in_scheme(&self, path: impl AsRef<Path>) -> PathBuf {
        let mut canonical_path = PathBuf::from(&self.scheme);
        // Should be a little careful here, not sure I want this behavior
        if path.as_ref().is_absolute() {
            // This is nasty
            canonical_path.push(path.as_ref().to_string_lossy()[1..].to_string());
        } else {
            canonical_path.push(path);
        }
        canonical_path
    }
}

impl Default for Config {
    /// The default base scheme is `file:`.
    ///
    /// The default auth delay is 3 seconds.
    ///
    /// The default min and max ids are 1000 and 6000.
    fn default() -> Config {
        Config {
            scheme: String::from(DEFAULT_SCHEME),
            auth_delay: Duration::new(DEFAULT_TIMEOUT, 0),
            min_id: MIN_ID,
            max_id: MAX_ID,
            lock: Lock::Shared,
        }
    }
}

// Nasty hack to prevent the compiler complaining about
// "leaking" `AllInner`
mod sealed {
    use crate::Config;

    pub trait Name {
        fn name(&self) -> &str;
    }

    pub trait Id {
        fn id(&self) -> usize;
    }

    pub trait AllInner {
        // Group+User, thanks Dad
        type Gruser: Name + Id;

        /// These functions grab internal elements so that the other
        /// methods of `All` can manipulate them.
        fn list(&self) -> &Vec<Self::Gruser>;
        fn list_mut(&mut self) -> &mut Vec<Self::Gruser>;
        fn config(&self) -> &Config;
    }
}

use sealed::{AllInner, Id, Name};

/// This trait is used to remove repetitive API items from
/// [`AllGroups`] and [`AllUsers`]. It uses a hidden trait
/// so that the implementations of functions can be implemented
/// at the trait level. Do not try to implement this trait.
pub trait All: AllInner {
    /// Get an iterator borrowing all [`User`]s or [`Group`]s on the system.
    fn iter(&self) -> Iter<<Self as AllInner>::Gruser> {
        self.list().iter()
    }

    /// Get an iterator mutably borrowing all [`User`]s or [`Group`]s on the
    /// system.
    fn iter_mut(&mut self) -> IterMut<<Self as AllInner>::Gruser> {
        self.list_mut().iter_mut()
    }

    /// Borrow the [`User`] or [`Group`] with a given name.
    ///
    /// # Examples
    ///
    /// Basic usage:
    ///
    /// ```no_run
    /// # use redox_users::{All, AllUsers, Config};
    /// let users = AllUsers::basic(Config::default()).unwrap();
    /// let user = users.get_by_name("root").unwrap();
    /// ```
    fn get_by_name(&self, name: impl AsRef<str>) -> Option<&<Self as AllInner>::Gruser> {
        self.iter()
            .find(|gruser| gruser.name() == name.as_ref() )
    }

    /// Mutable version of [`All::get_by_name`].
    fn get_mut_by_name(&mut self, name: impl AsRef<str>) -> Option<&mut <Self as AllInner>::Gruser> {
        self.iter_mut()
            .find(|gruser| gruser.name() == name.as_ref() )
    }

    /// Borrow the [`User`] or [`Group`] with the given ID.
    ///
    /// # Examples
    ///
    /// Basic usage:
    ///
    /// ```no_run
    /// # use redox_users::{All, AllUsers, Config};
    /// let users = AllUsers::basic(Config::default()).unwrap();
    /// let user = users.get_by_id(0).unwrap();
    /// ```
    fn get_by_id(&self, id: usize) -> Option<&<Self as AllInner>::Gruser> {
        self.iter()
            .find(|gruser| gruser.id() == id )
    }

    /// Mutable version of [`All::get_by_id`].
    fn get_mut_by_id(&mut self, id: usize) -> Option<&mut <Self as AllInner>::Gruser> {
        self.iter_mut()
            .find(|gruser| gruser.id() == id )
    }

    /// Provides an unused id based on the min and max values in the [`Config`]
    /// passed to the `All`'s constructor.
    ///
    /// # Examples
    ///
    /// ```no_run
    /// # use redox_users::{All, AllUsers, Config};
    /// let users = AllUsers::basic(Config::default()).unwrap();
    /// let uid = users.get_unique_id().expect("no available uid");
    /// ```
    fn get_unique_id(&self) -> Option<usize> {
        for id in self.config().min_id..self.config().max_id {
            if !self.iter().any(|gruser| gruser.id() == id ) {
                return Some(id)
            }
        }
        None
    }

    /// Remove a [`User`] or [`Group`] from this `All` given it's name. If the
    /// Gruser was removed return `true`, else return `false`. This ensures
    /// that the Gruser no longer exists.
    fn remove_by_name(&mut self, name: impl AsRef<str>) -> bool {
        let list = self.list_mut();
        let indx = list.iter()
            .enumerate()
            .find_map(|(indx, gruser)| if gruser.name() == name.as_ref() {
                    Some(indx)
                } else {
                    None
                });
        if let Some(indx) = indx {
            list.remove(indx);
            true
        } else {
            false
        }
    }

    /// Id version of [`All::remove_by_name`].
    fn remove_by_id(&mut self, id: usize) -> bool {
        let list = self.list_mut();
        let indx = list.iter()
            .enumerate()
            .find_map(|(indx, gruser)| if gruser.id() == id {
                    Some(indx)
                } else {
                    None
                });
        if let Some(indx) = indx {
            list.remove(indx);
            true
        } else {
            false
        }
    }
}

/// `AllUsers` provides (borrowed) access to all the users on the system.
/// Note that this struct implements [`All`] for all of its access functions.
///
/// # Notes
/// Note that everything in this section also applies to [`AllGroups`].
///
/// * If you mutate anything owned by an `AllUsers`, you must call the
///   [`AllUsers::save`] in order for those changes to be applied to the system.
/// * The API here is kept small. Most mutating actions can be accomplished via
///   the [`All::get_mut_by_id`] and [`All::get_mut_by_name`]
///   functions.
#[derive(Debug)]
pub struct AllUsers<A> {
    users: Vec<User<A>>,
    config: Config,

    // Hold on to the locked fds to prevent race conditions
    #[allow(dead_code)]
    passwd_fd: File,
    #[allow(dead_code)]
    shadow_fd: Option<File>,
}

impl<A: Default> AllUsers<A> {
    pub fn new(config: Config) -> Result<AllUsers<A>, Error> {
        let mut passwd_fd = locked_file(config.in_scheme(PASSWD_FILE), config.lock)?;
        let mut passwd_cntnt = String::new();
        passwd_fd.read_to_string(&mut passwd_cntnt)?;

        let mut passwd_entries = Vec::new();
        for (indx, line) in passwd_cntnt.lines().enumerate() {
            let mut user = User::from_passwd_entry(line, indx)?;
            user.auth_delay = config.auth_delay;
            passwd_entries.push(user);
        }

        Ok(AllUsers::<A> {
            users: passwd_entries,
            config,
            passwd_fd,
            shadow_fd: None,
        })
    }
}

impl AllUsers<auth::Basic> {
    /// Provide access to all user information on the system except
    /// authentication. This is adequate for almost all uses of `AllUsers`.
    pub fn basic(config: Config) -> Result<AllUsers<auth::Basic>, Error> {
        Self::new(config)
    }
}

#[cfg(feature = "auth")]
impl AllUsers<auth::Full> {
    /// If access to password related methods for the [`User`]s yielded by this
    /// `AllUsers` is required, use this constructor.
    pub fn authenticator(config: Config) -> Result<AllUsers<auth::Full>, Error> {
        let mut shadow_fd = locked_file(config.in_scheme(SHADOW_FILE), config.lock)?;
        let mut shadow_cntnt = String::new();
        shadow_fd.read_to_string(&mut shadow_cntnt)?;
        let shadow_entries: Vec<&str> = shadow_cntnt.lines().collect();

        let mut new = Self::new(config)?;
        new.shadow_fd = Some(shadow_fd);

        for (indx, entry) in shadow_entries.iter().enumerate() {
            let mut entry = entry.split(';');
            let name = entry.next().ok_or(parse_error(indx,
                "error parsing shadowfile: expected username"
            ))?;
            let hash = entry.next().ok_or(parse_error(indx,
                "error parsing shadowfile: expected hash"
            ))?;
            new.users
                .iter_mut()
                .find(|user| user.user == name)
                .ok_or(parse_error(indx,
                    "error parsing shadowfile: unkown user"
                ))?.auth.hash = hash.to_string();
        }

        shadow_cntnt.zeroize();
        Ok(new)
    }

    /// Consumes a builder, adding a new user to this `AllUsers`. Returns a
    /// reference to the created user.
    ///
    /// Make sure to call [`AllUsers::save`] in order for the new user to be
    /// applied to the system.
    ///
    /// Note that the user's password is set unset (see
    /// [Unset vs Blank Passwords](struct.User.html#unset-vs-blank-passwords))
    /// during this call.
    ///
    /// Also note that the user is not added to any groups when this builder is
    /// consumed. In order to keep the system in a consistent state, it is
    /// reccomended to also use an instance of [`AllGroups`] to update group
    /// information when creating new users.
    ///
    /// # Defaults
    /// Fields not passed to the builder before calling this function are as
    /// follows:
    /// - `uid`: [`AllUsers::get_unique_id`] is called on self to get the next
    ///   available id.
    /// - `gid`: `99`. This is the default UID for the group `nobody`. Note
    ///   that the user is NOT added to this group in `/etc/groups`.
    /// - `name`: The login name passed to [`UserBuilder::new`].
    /// - `home`: `"/"`
    /// - `shell`: `file:/bin/ion`
    pub fn add_user(&mut self, builder: UserBuilder) -> Result<&User<auth::Full>, Error> {
        if !is_valid_name(&builder.user) {
            return Err(Error::InvalidName { name: builder.user });
        }

        let uid = builder.uid.unwrap_or_else(||
            self.get_unique_id()
                .expect("no remaining unused user ids")
        );

        if self.iter().any(|user| user.user == builder.user || user.uid == uid) {
            Err(Error::UserAlreadyExists)
        } else {
            self.users.push(User {
                user: builder.user.clone(),
                uid,
                gid: builder.gid.unwrap_or(99),
                name: builder.name.unwrap_or(builder.user),
                home: builder.home.unwrap_or("/".to_string()),
                shell: builder.shell.unwrap_or("file:/bin/ion".to_string()),
                auth: auth::Full::unset(),
                auth_delay: self.config.auth_delay
            });
            Ok(&self.users[self.users.len() - 1])
        }
    }

    /// Syncs the data stored in the `AllUsers` instance to the filesystem.
    /// To apply changes to the system from an `AllUsers`, you MUST call this
    /// function!
    pub fn save(&mut self) -> Result<(), Error> {
        let mut userstring = String::new();

        // Need to be careful to prevent allocations here so that
        // shadowstring can be zeroed when this process is complete.
        // 1 is suppossedly parallelism, not sure exactly what this means.
        // 16 is the max length of a u64, which is used as the salt.
        // 2 accounts for the semicolon separator and newline
        let acfg = argon2::Config::default();
        let argon_len = argon2::encoded_len(
            acfg.variant, acfg.mem_cost, acfg.time_cost,
            1, 16, acfg.hash_length) as usize;
        let mut shadowstring = String::with_capacity(
            self.users.len() * (USERNAME_LEN_MAX + argon_len + 2)
        );

        for user in &self.users {
            userstring.push_str(&user.passwd_entry()?);

            let mut shadow_entry = user.shadow_entry()?;
            shadowstring.push_str(&shadow_entry);

            shadow_entry.zeroize();
        }

        let mut shadow_fd = self.shadow_fd.as_mut()
            .expect("shadow_fd should exist for AllUsers<auth::Full>");

        reset_file(&mut self.passwd_fd)?;
        self.passwd_fd.write_all(userstring.as_bytes())?;

        reset_file(&mut shadow_fd)?;
        shadow_fd.write_all(shadowstring.as_bytes())?;

        shadowstring.zeroize();
        Ok(())
    }
}

impl<A> AllInner for AllUsers<A> {
    type Gruser = User<A>;

    fn list(&self) -> &Vec<Self::Gruser> {
        &self.users
    }

    fn list_mut(&mut self) -> &mut Vec<Self::Gruser> {
        &mut self.users
    }

    fn config(&self) -> &Config {
        &self.config
    }
}

impl<A> All for AllUsers<A> {}
/*
#[cfg(not(target_os = "redox"))]
impl<A> Drop for AllUsers<A> {
    fn drop(&mut self) {
        eprintln!("Dropping AllUsers");
        let _ = flock(self.passwd_fd.as_raw_fd(), FlockArg::Unlock);
        if let Some(fd) = self.shadow_fd.as_ref() {
            eprintln!("Shadow");
            let _ = flock(fd.as_raw_fd(), FlockArg::Unlock);
        }
    }
}
*/
/// `AllGroups` provides (borrowed) access to all groups on the system. Note
/// that this struct implements [`All`] for all of its access functions.
///
/// General notes that also apply to this struct may be found with
/// [`AllUsers`].
#[derive(Debug)]
pub struct AllGroups {
    groups: Vec<Group>,
    config: Config,

    group_fd: File,
}

impl AllGroups {
    /// Create a new `AllGroups`.
    pub fn new(config: Config) -> Result<AllGroups, Error> {
        let mut group_fd = locked_file(config.in_scheme(GROUP_FILE), config.lock)?;
        let mut group_cntnt = String::new();
        group_fd.read_to_string(&mut group_cntnt)?;

        let mut entries: Vec<Group> = Vec::new();
        for (indx, line) in group_cntnt.lines().enumerate() {
            let group = Group::from_group_entry(line, indx)?;
            entries.push(group);
        }

        Ok(AllGroups {
            groups: entries,
            config,
            group_fd,
        })
    }

    /// Consumes a builder, adding a new group to this `AllGroups`. Returns a
    /// reference to the created `Group`.
    ///
    /// Make sure to call [`AllGroups::save`] in order for the new group to be
    /// applied to the system.
    ///
    /// # Defaults
    /// If a builder is not passed a group id ([`GroupBuilder::gid`]) before
    /// being passed to this function, [`AllGroups::get_unique_id`] is used.
    ///
    /// If the builder is not passed any users ([`GroupBuilder::user`]), the
    /// group will still be created.
    pub fn add_group(&mut self, builder: GroupBuilder) -> Result<&Group, Error> {
        let group_exists = self.iter()
            .any(|group| {
                let gid_taken = if let Some(gid) = builder.gid {
                    group.gid == gid
                } else {
                    false
                };
                group.group == builder.group || gid_taken
            });

        if group_exists {
            Err(Error::GroupAlreadyExists)
        } else if !is_valid_name(&builder.group) {
            Err(Error::InvalidName { name: builder.group })
        } else {
            for username in builder.users.iter() {
                if !is_valid_name(username) {
                    return Err(Error::InvalidName { name: username.to_string() });
                }
            }

            self.groups.push(Group {
                group: builder.group,
                gid: builder.gid.unwrap_or_else(||
                    self.get_unique_id()
                        .expect("no remaining unused group IDs")
                ),
                users: builder.users,
            });
            Ok(&self.groups[self.groups.len() - 1])
        }
    }

    /// Syncs the data stored in this `AllGroups` instance to the filesystem.
    /// To apply changes from an `AllGroups`, you MUST call this function!
    pub fn save(&mut self) -> Result<(), Error> {
        let mut groupstring = String::new();
        for group in &self.groups {
            groupstring.push_str(&group.group_entry()?);
        }

        reset_file(&mut self.group_fd)?;
        self.group_fd.write_all(groupstring.as_bytes())?;
        Ok(())
    }
}

impl AllInner for AllGroups {
    type Gruser = Group;

    fn list(&self) -> &Vec<Self::Gruser> {
        &self.groups
    }

    fn list_mut(&mut self) -> &mut Vec<Self::Gruser> {
        &mut self.groups
    }

    fn config(&self) -> &Config {
        &self.config
    }
}

impl All for AllGroups {}
/*
#[cfg(not(target_os = "redox"))]
impl Drop for AllGroups {
    fn drop(&mut self) {
        eprintln!("Dropping AllGroups");
        let _ = flock(self.group_fd.as_raw_fd(), FlockArg::Unlock);
    }
}*/

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

    const TEST_PREFIX: &'static str = "tests";

    /// Needed for the file checks, this is done by the library
    fn test_prefix(filename: &str) -> String {
        let mut complete = String::from(TEST_PREFIX);
        complete.push_str(filename);
        complete
    }

    #[test]
    fn test_safe_string() {
        assert!(is_safe_string("Hello\\$!"));
        assert!(!is_safe_string("semicolons are awesome; yeah!"));
    }

    #[test]
    fn test_portable_filename() {
        let valid = |s| {
            assert!(is_valid_name(s));
        };
        let invld = |s| {
            assert!(!is_valid_name(s));
        };
        valid("valid");
        valid("vld.io");
        valid("hyphen-ated");
        valid("under_scores");
        valid("1334");

        invld("-no_flgs");
        invld("invalid!");
        invld("also:invalid");
        invld("coolie-o?");
        invld("sh");
        invld("avery_very_very_very_loooooooonnggg-username");
    }

    fn test_cfg() -> Config {
        Config::default()
            // Since all this really does is prepend `sheme` to the consts
            .scheme(TEST_PREFIX.to_string())
            .writeable(true)
    }

    fn read_locked_file(file: impl AsRef<Path>) -> Result<String, Error> {
        let mut fd = locked_file(file, Lock::Shared)?;
        let mut cntnt = String::new();
        fd.read_to_string(&mut cntnt)?;
        Ok(cntnt)
    }

    // *** struct.User ***
    #[cfg(feature = "auth")]
    #[test]
    fn attempt_user_api() {
        let mut users = AllUsers::authenticator(test_cfg()).unwrap();
        let user = users.get_mut_by_id(1000).unwrap();

        assert_eq!(user.is_passwd_blank(), true);
        assert_eq!(user.is_passwd_unset(), false);
        assert_eq!(user.verify_passwd(""), true);
        assert_eq!(user.verify_passwd("Something"), false);

        user.set_passwd("hi,i_am_passwd").unwrap();

        assert_eq!(user.is_passwd_blank(), false);
        assert_eq!(user.is_passwd_unset(), false);
        assert_eq!(user.verify_passwd(""), false);
        assert_eq!(user.verify_passwd("Something"), false);
        assert_eq!(user.verify_passwd("hi,i_am_passwd"), true);

        user.unset_passwd();

        assert_eq!(user.is_passwd_blank(), false);
        assert_eq!(user.is_passwd_unset(), true);
        assert_eq!(user.verify_passwd(""), false);
        assert_eq!(user.verify_passwd("Something"), false);
        assert_eq!(user.verify_passwd("hi,i_am_passwd"), false);

        user.set_passwd("").unwrap();

        assert_eq!(user.is_passwd_blank(), true);
        assert_eq!(user.is_passwd_unset(), false);
        assert_eq!(user.verify_passwd(""), true);
        assert_eq!(user.verify_passwd("Something"), false);
    }

    // *** struct.AllUsers ***
    #[cfg(feature = "auth")]
    #[test]
    fn get_user() {
        let users = AllUsers::authenticator(test_cfg()).unwrap();

        let root = users.get_by_id(0).expect("'root' user missing");
        assert_eq!(root.user, "root".to_string());
        assert_eq!(root.auth.hash.as_str(),
            "$argon2i$m=4096,t=10,p=1$Tnc4UVV0N00$ML9LIOujd3nmAfkAwEcSTMPqakWUF0OUiLWrIy0nGLk");
        assert_eq!(root.uid, 0);
        assert_eq!(root.gid, 0);
        assert_eq!(root.name, "root".to_string());
        assert_eq!(root.home, "file:/root".to_string());
        assert_eq!(root.shell, "file:/bin/ion".to_string());

        let user = users.get_by_name("user").expect("'user' user missing");
        assert_eq!(user.user, "user".to_string());
        assert_eq!(user.auth.hash.as_str(), "");
        assert_eq!(user.uid, 1000);
        assert_eq!(user.gid, 1000);
        assert_eq!(user.name, "user".to_string());
        assert_eq!(user.home, "file:/home/user".to_string());
        assert_eq!(user.shell, "file:/bin/ion".to_string());
        println!("{:?}", users);

        let li = users.get_by_name("loip").expect("'loip' user missing");
        println!("got loip");
        assert_eq!(li.user, "loip");
        assert_eq!(li.auth.hash.as_str(), "!");
        assert_eq!(li.uid, 1007);
        assert_eq!(li.gid, 1007);
        assert_eq!(li.name, "Lorem".to_string());
        assert_eq!(li.home, "file:/home/lorem".to_string());
        assert_eq!(li.shell, "file:/bin/ion".to_string());
    }

    #[cfg(feature = "auth")]
    #[test]
    fn manip_user() {
        let mut users = AllUsers::authenticator(test_cfg()).unwrap();
        // NOT testing `get_unique_id`
        let id = 7099;

        let fb = UserBuilder::new("fbar")
            .uid(id)
            .gid(id)
            .name("Foo Bar")
            .home("/home/foob")
            .shell("/bin/zsh");

        users
            .add_user(fb)
            .expect("failed to add user 'fbar'");
        //                                            weirdo ^^^^^^^^ :P
        users.save().unwrap();
        let p_file_content = read_locked_file(test_prefix(PASSWD_FILE)).unwrap();
        assert_eq!(
            p_file_content,
            concat!(
                "root;0;0;root;file:/root;file:/bin/ion\n",
                "user;1000;1000;user;file:/home/user;file:/bin/ion\n",
                "loip;1007;1007;Lorem;file:/home/lorem;file:/bin/ion\n",
                "fbar;7099;7099;Foo Bar;/home/foob;/bin/zsh\n"
            )
        );
        let s_file_content = read_locked_file(test_prefix(SHADOW_FILE)).unwrap();
        assert_eq!(s_file_content, concat!(
            "root;$argon2i$m=4096,t=10,p=1$Tnc4UVV0N00$ML9LIOujd3nmAfkAwEcSTMPqakWUF0OUiLWrIy0nGLk\n",
            "user;\n",
            "loip;!\n",
            "fbar;!\n"
        ));

        {
            println!("{:?}", users);
            let fb = users.get_mut_by_name("fbar")
                .expect("'fbar' user missing");
            fb.shell = "/bin/fish".to_string(); // That's better
            fb.set_passwd("").unwrap();
        }
        users.save().unwrap();
        let p_file_content = read_locked_file(test_prefix(PASSWD_FILE)).unwrap();
        assert_eq!(
            p_file_content,
            concat!(
                "root;0;0;root;file:/root;file:/bin/ion\n",
                "user;1000;1000;user;file:/home/user;file:/bin/ion\n",
                "loip;1007;1007;Lorem;file:/home/lorem;file:/bin/ion\n",
                "fbar;7099;7099;Foo Bar;/home/foob;/bin/fish\n"
            )
        );
        let s_file_content = read_locked_file(test_prefix(SHADOW_FILE)).unwrap();
        assert_eq!(s_file_content, concat!(
            "root;$argon2i$m=4096,t=10,p=1$Tnc4UVV0N00$ML9LIOujd3nmAfkAwEcSTMPqakWUF0OUiLWrIy0nGLk\n",
            "user;\n",
            "loip;!\n",
            "fbar;\n"
        ));

        users.remove_by_id(id);
        users.save().unwrap();
        let file_content = read_locked_file(test_prefix(PASSWD_FILE)).unwrap();
        assert_eq!(
            file_content,
            concat!(
                "root;0;0;root;file:/root;file:/bin/ion\n",
                "user;1000;1000;user;file:/home/user;file:/bin/ion\n",
                "loip;1007;1007;Lorem;file:/home/lorem;file:/bin/ion\n"
            )
        );
    }

    /* struct.Group */
    #[test]
    fn empty_groups() {
        let group_trailing = Group::from_group_entry("nobody;2066; ", 0).unwrap();
        assert_eq!(group_trailing.users.len(), 0);

        let group_no_trailing = Group::from_group_entry("nobody;2066;", 0).unwrap();
        assert_eq!(group_no_trailing.users.len(), 0);

        assert_eq!(group_trailing.group, group_no_trailing.group);
        assert_eq!(group_trailing.gid, group_no_trailing.gid);
        assert_eq!(group_trailing.users, group_no_trailing.users);
    }

    /* struct.AllGroups */
    #[test]
    fn get_group() {
        let groups = AllGroups::new(test_cfg()).unwrap();
        let user = groups.get_by_name("user").unwrap();
        assert_eq!(user.group, "user");
        assert_eq!(user.gid, 1000);
        assert_eq!(user.users, vec!["user"]);

        let wheel = groups.get_by_id(1).unwrap();
        assert_eq!(wheel.group, "wheel");
        assert_eq!(wheel.gid, 1);
        assert_eq!(wheel.users, vec!["user", "root"]);
    }

    #[test]
    fn manip_group() {
        let id = 7099;
        let mut groups = AllGroups::new(test_cfg()).unwrap();

        let fb = GroupBuilder::new("fbar")
            // NOT testing `get_unique_id`
            .gid(id)
            .user("fbar");

        groups.add_group(fb).unwrap();
        groups.save().unwrap();
        let file_content = read_locked_file(test_prefix(GROUP_FILE)).unwrap();
        assert_eq!(
            file_content,
            concat!(
                "root;0;root\n",
                "user;1000;user\n",
                "wheel;1;user,root\n",
                "loip;1007;loip\n",
                "fbar;7099;fbar\n"
            )
        );

        {
            let fb = groups.get_mut_by_name("fbar").unwrap();
            fb.users.push("user".to_string());
        }
        groups.save().unwrap();
        let file_content = read_locked_file(test_prefix(GROUP_FILE)).unwrap();
        assert_eq!(
            file_content,
            concat!(
                "root;0;root\n",
                "user;1000;user\n",
                "wheel;1;user,root\n",
                "loip;1007;loip\n",
                "fbar;7099;fbar,user\n"
            )
        );

        groups.remove_by_id(id);
        groups.save().unwrap();
        let file_content = read_locked_file(test_prefix(GROUP_FILE)).unwrap();
        assert_eq!(
            file_content,
            concat!(
                "root;0;root\n",
                "user;1000;user\n",
                "wheel;1;user,root\n",
                "loip;1007;loip\n"
            )
        );
    }

    #[test]
    fn empty_group() {
        let mut groups = AllGroups::new(test_cfg()).unwrap();
        let nobody = GroupBuilder::new("nobody")
            .gid(2260);

        groups.add_group(nobody).unwrap();
        groups.save().unwrap();
        let file_content = read_locked_file(test_prefix(GROUP_FILE)).unwrap();
        assert_eq!(
            file_content,
            concat!(
                "root;0;root\n",
                "user;1000;user\n",
                "wheel;1;user,root\n",
                "loip;1007;loip\n",
                "nobody;2260;\n",
            )
        );

        drop(groups);
        let mut groups = AllGroups::new(test_cfg()).unwrap();

        groups.remove_by_name("nobody");
        groups.save().unwrap();

        let file_content = read_locked_file(test_prefix(GROUP_FILE)).unwrap();
        assert_eq!(
            file_content,
            concat!(
                "root;0;root\n",
                "user;1000;user\n",
                "wheel;1;user,root\n",
                "loip;1007;loip\n"
            )
        );
    }

    // *** Misc ***
    #[test]
    fn users_get_unused_ids() {
        let users = AllUsers::basic(test_cfg()).unwrap();
        let id = users.get_unique_id().unwrap();
        if id < users.config.min_id || id > users.config.max_id {
            panic!("User ID is not between allowed margins")
        } else if let Some(_) = users.get_by_id(id) {
            panic!("User ID is used!");
        }
    }

    #[test]
    fn groups_get_unused_ids() {
        let groups = AllGroups::new(test_cfg()).unwrap();
        let id = groups.get_unique_id().unwrap();
        if id < groups.config.min_id || id > groups.config.max_id {
            panic!("Group ID is not between allowed margins")
        } else if let Some(_) = groups.get_by_id(id) {
            panic!("Group ID is used!");
        }
    }
}
