// Copyright 2018 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

use libc;

use std::cmp::min;
use std::collections::{btree_map, BTreeMap};
use std::ffi::CString;
use std::fs;
use std::io::{self, Cursor, Read, Write};
use std::mem;
use std::os::linux::fs::MetadataExt;
use std::os::unix::fs::{DirBuilderExt, FileExt, OpenOptionsExt};
use std::os::unix::io::AsRawFd;
use std::path::{Component, Path, PathBuf};

use protocol::*;

// Tlopen and Tlcreate flags.  Taken from "include/net/9p/9p.h" in the linux tree.
const _P9_RDONLY: u32 = 0o00000000;
const P9_WRONLY: u32 = 0o00000001;
const P9_RDWR: u32 = 0o00000002;
const P9_NOACCESS: u32 = 0o00000003;
const P9_CREATE: u32 = 0o00000100;
const P9_EXCL: u32 = 0o00000200;
const P9_NOCTTY: u32 = 0o00000400;
const P9_TRUNC: u32 = 0o00001000;
const P9_APPEND: u32 = 0o00002000;
const P9_NONBLOCK: u32 = 0o00004000;
const P9_DSYNC: u32 = 0o00010000;
const P9_FASYNC: u32 = 0o00020000;
const P9_DIRECT: u32 = 0o00040000;
const P9_LARGEFILE: u32 = 0o00100000;
const P9_DIRECTORY: u32 = 0o00200000;
const P9_NOFOLLOW: u32 = 0o00400000;
const P9_NOATIME: u32 = 0o01000000;
const _P9_CLOEXEC: u32 = 0o02000000;
const P9_SYNC: u32 = 0o04000000;

// Mapping from 9P flags to libc flags.
const MAPPED_FLAGS: [(u32, i32); 10] = [
    (P9_NOCTTY, libc::O_NOCTTY),
    (P9_NONBLOCK, libc::O_NONBLOCK),
    (P9_DSYNC, libc::O_DSYNC),
    (P9_FASYNC, 0), // Unsupported
    (P9_DIRECT, libc::O_DIRECT),
    (P9_LARGEFILE, libc::O_LARGEFILE),
    (P9_DIRECTORY, libc::O_DIRECTORY),
    (P9_NOFOLLOW, libc::O_NOFOLLOW),
    (P9_NOATIME, libc::O_NOATIME),
    (P9_SYNC, libc::O_SYNC),
];

// 9P Qid types.  Taken from "include/net/9p/9p.h" in the linux tree.
const P9_QTDIR: u8 = 0x80;
const _P9_QTAPPEND: u8 = 0x40;
const _P9_QTEXCL: u8 = 0x20;
const _P9_QTMOUNT: u8 = 0x10;
const _P9_QTAUTH: u8 = 0x08;
const _P9_QTTMP: u8 = 0x04;
const _P9_QTSYMLINK: u8 = 0x02;
const _P9_QTLINK: u8 = 0x01;
const P9_QTFILE: u8 = 0x00;

// Bitmask values for the getattr request.
const _P9_GETATTR_MODE: u64 = 0x00000001;
const _P9_GETATTR_NLINK: u64 = 0x00000002;
const _P9_GETATTR_UID: u64 = 0x00000004;
const _P9_GETATTR_GID: u64 = 0x00000008;
const _P9_GETATTR_RDEV: u64 = 0x00000010;
const _P9_GETATTR_ATIME: u64 = 0x00000020;
const _P9_GETATTR_MTIME: u64 = 0x00000040;
const _P9_GETATTR_CTIME: u64 = 0x00000080;
const _P9_GETATTR_INO: u64 = 0x00000100;
const _P9_GETATTR_SIZE: u64 = 0x00000200;
const _P9_GETATTR_BLOCKS: u64 = 0x00000400;

const _P9_GETATTR_BTIME: u64 = 0x00000800;
const _P9_GETATTR_GEN: u64 = 0x00001000;
const _P9_GETATTR_DATA_VERSION: u64 = 0x00002000;

const P9_GETATTR_BASIC: u64 = 0x000007ff; /* Mask for fields up to BLOCKS */
const _P9_GETATTR_ALL: u64 = 0x00003fff; /* Mask for All fields above */

// Bitmask values for the setattr request.
const P9_SETATTR_MODE: u32 = 0x00000001;
const P9_SETATTR_UID: u32 = 0x00000002;
const P9_SETATTR_GID: u32 = 0x00000004;
const P9_SETATTR_SIZE: u32 = 0x00000008;
const P9_SETATTR_ATIME: u32 = 0x00000010;
const P9_SETATTR_MTIME: u32 = 0x00000020;
const P9_SETATTR_CTIME: u32 = 0x00000040;
const P9_SETATTR_ATIME_SET: u32 = 0x00000080;
const P9_SETATTR_MTIME_SET: u32 = 0x00000100;

// Minimum and maximum message size that we'll expect from the client.
const MIN_MESSAGE_SIZE: u32 = 256;
const MAX_MESSAGE_SIZE: u32 = ::std::u16::MAX as u32;

// Represents state that the server is holding on behalf of a client. Fids are somewhat like file
// descriptors but are not restricted to open files and directories. Fids are identified by a unique
// 32-bit number chosen by the client. Most messages sent by clients include a fid on which to
// operate. The fid in a Tattach message represents the root of the file system tree that the client
// is allowed to access. A client can create more fids by walking the directory tree from that fid.
struct Fid {
    path: Box<Path>,
    metadata: fs::Metadata,
    file: Option<fs::File>,
    dirents: Option<Vec<Dirent>>,
}

fn metadata_to_qid(metadata: &fs::Metadata) -> Qid {
    let ty = if metadata.is_dir() {
        P9_QTDIR
    } else if metadata.is_file() {
        P9_QTFILE
    } else {
        // Unknown file type...
        0
    };

    Qid {
        ty: ty,
        // TODO: deal with the 2038 problem before 2038
        version: metadata.st_mtime() as u32,
        path: metadata.st_ino(),
    }
}

fn error_to_rmessage(err: io::Error) -> Rmessage {
    let errno = if let Some(errno) = err.raw_os_error() {
        errno
    } else {
        // Make a best-effort guess based on the kind.
        match err.kind() {
            io::ErrorKind::NotFound => libc::ENOENT,
            io::ErrorKind::PermissionDenied => libc::EPERM,
            io::ErrorKind::ConnectionRefused => libc::ECONNREFUSED,
            io::ErrorKind::ConnectionReset => libc::ECONNRESET,
            io::ErrorKind::ConnectionAborted => libc::ECONNABORTED,
            io::ErrorKind::NotConnected => libc::ENOTCONN,
            io::ErrorKind::AddrInUse => libc::EADDRINUSE,
            io::ErrorKind::AddrNotAvailable => libc::EADDRNOTAVAIL,
            io::ErrorKind::BrokenPipe => libc::EPIPE,
            io::ErrorKind::AlreadyExists => libc::EEXIST,
            io::ErrorKind::WouldBlock => libc::EWOULDBLOCK,
            io::ErrorKind::InvalidInput => libc::EINVAL,
            io::ErrorKind::InvalidData => libc::EINVAL,
            io::ErrorKind::TimedOut => libc::ETIMEDOUT,
            io::ErrorKind::WriteZero => libc::EIO,
            io::ErrorKind::Interrupted => libc::EINTR,
            io::ErrorKind::Other => libc::EIO,
            io::ErrorKind::UnexpectedEof => libc::EIO,
            _ => libc::EIO,
        }
    };

    Rmessage::Lerror(Rlerror {
        ecode: errno as u32,
    })
}

// Joins `path` to `buf`.  If `path` is '..', removes the last component from `buf`
// only if `buf` != `root` but does nothing if `buf` == `root`.  Pushes `path` onto
// `buf` if it is a normal path component.
//
// Returns an error if `path` is absolute, has more than one component, or contains
// a '.' component.
fn join_path<P: AsRef<Path>, R: AsRef<Path>>(
    mut buf: PathBuf,
    path: P,
    root: R,
) -> io::Result<PathBuf> {
    let path = path.as_ref();
    let root = root.as_ref();
    debug_assert!(buf.starts_with(root));

    if path.components().count() > 1 {
        return Err(io::Error::from_raw_os_error(libc::EINVAL));
    }

    for component in path.components() {
        match component {
            // Prefix should only appear on windows systems.
            Component::Prefix(_) => return Err(io::Error::from_raw_os_error(libc::EINVAL)),
            // Absolute paths are not allowed.
            Component::RootDir => return Err(io::Error::from_raw_os_error(libc::EINVAL)),
            // '.' elements are not allowed.
            Component::CurDir => return Err(io::Error::from_raw_os_error(libc::EINVAL)),
            Component::ParentDir => {
                // We only remove the parent path if we are not already at the root of the
                // file system.
                if buf != root {
                    buf.pop();
                }
            }
            Component::Normal(element) => buf.push(element),
        }
    }

    Ok(buf)
}

// TODO(b/124272076): remove mapping support once crosvm plugin implements 9p client.
pub type ServerIdMap<T> = BTreeMap<T, T>;
pub type ServerUidMap = ServerIdMap<libc::uid_t>;
pub type ServerGidMap = ServerIdMap<libc::gid_t>;

fn map_id_from_host<T: Clone + Ord>(map: &ServerIdMap<T>, id: T) -> T {
    map.get(&id).map_or(id.clone(), |v| v.clone())
}

pub struct Server {
    root: Box<Path>,
    msize: u32,
    fids: BTreeMap<u32, Fid>,
    uid_map: ServerUidMap,
    gid_map: ServerGidMap,
}

impl Server {
    pub fn new<P: AsRef<Path>>(root: P, uid_map: ServerUidMap, gid_map: ServerGidMap) -> Server {
        Server {
            root: root.as_ref().into(),
            msize: MAX_MESSAGE_SIZE,
            fids: BTreeMap::new(),
            uid_map: uid_map,
            gid_map: gid_map,
        }
    }

    pub fn handle_message<R: Read, W: Write>(
        &mut self,
        reader: &mut R,
        writer: &mut W,
    ) -> io::Result<()> {
        let request: Tframe = WireFormat::decode(&mut reader.take(self.msize as u64))?;

        if cfg!(feature = "trace") {
            println!("{:?}", &request);
        }

        let rmsg = match request.msg {
            Tmessage::Version(ref version) => self.version(version),
            Tmessage::Flush(ref flush) => self.flush(flush),
            Tmessage::Walk(ref walk) => self.walk(walk),
            Tmessage::Read(ref read) => self.read(read),
            Tmessage::Write(ref write) => self.write(write),
            Tmessage::Clunk(ref clunk) => self.clunk(clunk),
            Tmessage::Remove(ref remove) => self.remove(remove),
            Tmessage::Attach(ref attach) => self.attach(attach),
            Tmessage::Auth(ref auth) => self.auth(auth),
            Tmessage::Statfs(ref statfs) => self.statfs(statfs),
            Tmessage::Lopen(ref lopen) => self.lopen(lopen),
            Tmessage::Lcreate(ref lcreate) => self.lcreate(lcreate),
            Tmessage::Symlink(ref symlink) => self.symlink(symlink),
            Tmessage::Mknod(ref mknod) => self.mknod(mknod),
            Tmessage::Rename(ref rename) => self.rename(rename),
            Tmessage::Readlink(ref readlink) => self.readlink(readlink),
            Tmessage::GetAttr(ref get_attr) => self.get_attr(get_attr),
            Tmessage::SetAttr(ref set_attr) => self.set_attr(set_attr),
            Tmessage::XattrWalk(ref xattr_walk) => self.xattr_walk(xattr_walk),
            Tmessage::XattrCreate(ref xattr_create) => self.xattr_create(xattr_create),
            Tmessage::Readdir(ref readdir) => self.readdir(readdir),
            Tmessage::Fsync(ref fsync) => self.fsync(fsync),
            Tmessage::Lock(ref lock) => self.lock(lock),
            Tmessage::GetLock(ref get_lock) => self.get_lock(get_lock),
            Tmessage::Link(ref link) => self.link(link),
            Tmessage::Mkdir(ref mkdir) => self.mkdir(mkdir),
            Tmessage::RenameAt(ref rename_at) => self.rename_at(rename_at),
            Tmessage::UnlinkAt(ref unlink_at) => self.unlink_at(unlink_at),
        };

        // Errors while handling requests are never fatal.
        let response = Rframe {
            tag: request.tag,
            msg: rmsg.unwrap_or_else(error_to_rmessage),
        };

        if cfg!(feature = "trace") {
            println!("{:?}", &response);
        }

        response.encode(writer)?;
        writer.flush()
    }

    fn auth(&mut self, _auth: &Tauth) -> io::Result<Rmessage> {
        // Returning an error for the auth message means that the server does not require
        // authentication.
        Err(io::Error::from_raw_os_error(libc::EOPNOTSUPP))
    }

    fn attach(&mut self, attach: &Tattach) -> io::Result<Rmessage> {
        // TODO: Check attach parameters
        match self.fids.entry(attach.fid) {
            btree_map::Entry::Vacant(entry) => {
                let fid = Fid {
                    path: self.root.to_path_buf().into_boxed_path(),
                    metadata: fs::metadata(&self.root)?,
                    file: None,
                    dirents: None,
                };
                let response = Rattach {
                    qid: metadata_to_qid(&fid.metadata),
                };
                entry.insert(fid);
                Ok(Rmessage::Attach(response))
            }
            btree_map::Entry::Occupied(_) => Err(io::Error::from_raw_os_error(libc::EBADF)),
        }
    }

    fn version(&mut self, version: &Tversion) -> io::Result<Rmessage> {
        if version.msize < MIN_MESSAGE_SIZE {
            return Err(io::Error::from_raw_os_error(libc::EINVAL));
        }

        // A Tversion request clunks all open fids and terminates any pending I/O.
        self.fids.clear();
        self.msize = min(MAX_MESSAGE_SIZE, version.msize);

        Ok(Rmessage::Version(Rversion {
            msize: self.msize,
            version: if version.version == "9P2000.L" {
                String::from("9P2000.L")
            } else {
                String::from("unknown")
            },
        }))
    }

    fn flush(&mut self, _flush: &Tflush) -> io::Result<Rmessage> {
        // TODO: Since everything is synchronous we can't actually flush requests.
        Ok(Rmessage::Flush)
    }

    fn do_walk(
        &self,
        wnames: &[String],
        mut buf: PathBuf,
        mds: &mut Vec<fs::Metadata>,
    ) -> io::Result<PathBuf> {
        for wname in wnames {
            let name = Path::new(wname);
            buf = join_path(buf, name, &*self.root)?;
            mds.push(fs::metadata(&buf)?);
        }

        Ok(buf)
    }

    fn walk(&mut self, walk: &Twalk) -> io::Result<Rmessage> {
        // `newfid` must not currently be in use unless it is the same as `fid`.
        if walk.fid != walk.newfid && self.fids.contains_key(&walk.newfid) {
            return Err(io::Error::from_raw_os_error(libc::EBADF));
        }

        // We need to walk the tree.  First get the starting path.
        let (buf, oldmd) = self
            .fids
            .get(&walk.fid)
            .ok_or_else(|| io::Error::from_raw_os_error(libc::EBADF))
            .map(|fid| (fid.path.to_path_buf(), fid.metadata.clone()))?;

        // Now walk the tree and break on the first error, if any.
        let mut mds = Vec::with_capacity(walk.wnames.len());
        match self.do_walk(&walk.wnames, buf, &mut mds) {
            Ok(buf) => {
                // Store the new fid if the full walk succeeded.
                if mds.len() == walk.wnames.len() {
                    // This could just be a duplication operation.
                    let md = if let Some(md) = mds.last() {
                        md.clone()
                    } else {
                        oldmd
                    };

                    self.fids.insert(
                        walk.newfid,
                        Fid {
                            path: buf.into_boxed_path(),
                            metadata: md,
                            file: None,
                            dirents: None,
                        },
                    );
                }
            }
            Err(e) => {
                // Only return an error if it occurred on the first component.
                if mds.is_empty() {
                    return Err(e);
                }
            }
        }

        Ok(Rmessage::Walk(Rwalk {
            wqids: mds.iter().map(metadata_to_qid).collect(),
        }))
    }

    fn read(&mut self, read: &Tread) -> io::Result<Rmessage> {
        // Thankfully, `read` cannot be used to read directories in 9P2000.L.
        let file = self
            .fids
            .get_mut(&read.fid)
            .and_then(|fid| fid.file.as_mut())
            .ok_or_else(|| io::Error::from_raw_os_error(libc::EBADF))?;

        // Use an empty Rread struct to figure out the overhead of the header.
        let header_size = Rframe {
            tag: 0,
            msg: Rmessage::Read(Rread {
                data: Data(Vec::new()),
            }),
        }
        .byte_size();

        let capacity = min(self.msize - header_size, read.count);
        let mut buf = Data(Vec::with_capacity(capacity as usize));
        buf.resize(capacity as usize, 0);

        let count = file.read_at(&mut buf, read.offset)?;
        buf.resize(count, 0);

        Ok(Rmessage::Read(Rread { data: buf }))
    }

    fn write(&mut self, write: &Twrite) -> io::Result<Rmessage> {
        let file = self
            .fids
            .get_mut(&write.fid)
            .and_then(|fid| fid.file.as_mut())
            .ok_or_else(|| io::Error::from_raw_os_error(libc::EBADF))?;

        let count = file.write_at(&write.data, write.offset)?;
        Ok(Rmessage::Write(Rwrite {
            count: count as u32,
        }))
    }

    fn clunk(&mut self, clunk: &Tclunk) -> io::Result<Rmessage> {
        match self.fids.entry(clunk.fid) {
            btree_map::Entry::Vacant(_) => Err(io::Error::from_raw_os_error(libc::EBADF)),
            btree_map::Entry::Occupied(entry) => {
                entry.remove();
                Ok(Rmessage::Clunk)
            }
        }
    }

    fn remove(&mut self, remove: &Tremove) -> io::Result<Rmessage> {
        match self.fids.entry(remove.fid) {
            btree_map::Entry::Vacant(_) => Err(io::Error::from_raw_os_error(libc::EBADF)),
            btree_map::Entry::Occupied(o) => {
                let (_, fid) = o.remove_entry();

                if fid.metadata.is_dir() {
                    fs::remove_dir(&fid.path)?;
                } else {
                    fs::remove_file(&fid.path)?;
                }

                Ok(Rmessage::Remove)
            }
        }
    }

    fn statfs(&mut self, statfs: &Tstatfs) -> io::Result<Rmessage> {
        let fid = self
            .fids
            .get(&statfs.fid)
            .ok_or_else(|| io::Error::from_raw_os_error(libc::EBADF))?;
        let path = fid
            .path
            .to_str()
            .and_then(|path| CString::new(path).ok())
            .ok_or_else(|| io::Error::from_raw_os_error(libc::EINVAL))?;

        // Safe because we are zero-initializing a C struct with only primitive
        // data members.
        let mut out: libc::statfs64 = unsafe { mem::zeroed() };

        // Safe because we know that `path` is valid and we have already initialized `out`.
        let ret = unsafe { libc::statfs64(path.as_ptr(), &mut out) };
        if ret != 0 {
            return Err(io::Error::last_os_error());
        }

        Ok(Rmessage::Statfs(Rstatfs {
            ty: out.f_type as u32,
            bsize: out.f_bsize as u32,
            blocks: out.f_blocks,
            bfree: out.f_bfree,
            bavail: out.f_bavail,
            files: out.f_files,
            ffree: out.f_ffree,
            fsid: 0, // No way to get the fields of a libc::fsid_t
            namelen: out.f_namelen as u32,
        }))
    }

    fn lopen(&mut self, lopen: &Tlopen) -> io::Result<Rmessage> {
        let fid = self
            .fids
            .get_mut(&lopen.fid)
            .ok_or_else(|| io::Error::from_raw_os_error(libc::EBADF))?;
        // We always open files with O_CLOEXEC.
        let mut custom_flags: i32 = libc::O_CLOEXEC;
        for &(p9f, of) in &MAPPED_FLAGS {
            if (lopen.flags & p9f) != 0 {
                custom_flags |= of;
            }
        }

        let file = fs::OpenOptions::new()
            .read((lopen.flags & P9_NOACCESS) == 0 || (lopen.flags & P9_RDWR) != 0)
            .write((lopen.flags & P9_WRONLY) != 0 || (lopen.flags & P9_RDWR) != 0)
            .append((lopen.flags & P9_APPEND) != 0)
            .truncate((lopen.flags & P9_TRUNC) != 0)
            .create((lopen.flags & P9_CREATE) != 0)
            .create_new((lopen.flags & P9_CREATE) != 0 && (lopen.flags & P9_EXCL) != 0)
            .custom_flags(custom_flags)
            .open(&fid.path)?;

        fid.metadata = file.metadata()?;
        fid.file = Some(file);

        Ok(Rmessage::Lopen(Rlopen {
            qid: metadata_to_qid(&fid.metadata),
            iounit: 0,
        }))
    }

    fn lcreate(&mut self, lcreate: &Tlcreate) -> io::Result<Rmessage> {
        let fid = self
            .fids
            .get_mut(&lcreate.fid)
            .ok_or_else(|| io::Error::from_raw_os_error(libc::EBADF))?;

        if !fid.metadata.is_dir() {
            return Err(io::Error::from_raw_os_error(libc::ENOTDIR));
        }

        let name = Path::new(&lcreate.name);
        let path = join_path(fid.path.to_path_buf(), name, &*self.root)?;

        let mut custom_flags: i32 = libc::O_CLOEXEC;
        for &(p9f, of) in &MAPPED_FLAGS {
            if (lcreate.flags & p9f) != 0 {
                custom_flags |= of;
            }
        }

        let file = fs::OpenOptions::new()
            .read(false)
            .write(true)
            .truncate((lcreate.flags & P9_TRUNC) != 0)
            .create(true)
            .append((lcreate.flags & P9_APPEND) != 0)
            .create_new((lcreate.flags & P9_EXCL) != 0)
            .custom_flags(custom_flags)
            .mode(lcreate.mode & 0o755)
            .open(&path)?;

        fid.metadata = file.metadata()?;
        fid.file = Some(file);
        fid.path = path.into_boxed_path();

        Ok(Rmessage::Lcreate(Rlcreate {
            qid: metadata_to_qid(&fid.metadata),
            iounit: 0,
        }))
    }

    fn symlink(&mut self, _symlink: &Tsymlink) -> io::Result<Rmessage> {
        // symlinks are not allowed.
        Err(io::Error::from_raw_os_error(libc::EACCES))
    }

    fn mknod(&mut self, _mknod: &Tmknod) -> io::Result<Rmessage> {
        // No nodes either.
        Err(io::Error::from_raw_os_error(libc::EACCES))
    }

    fn rename(&mut self, rename: &Trename) -> io::Result<Rmessage> {
        let newname = Path::new(&rename.name);
        let buf = self
            .fids
            .get(&rename.dfid)
            .ok_or_else(|| io::Error::from_raw_os_error(libc::EBADF))
            .map(|dfid| dfid.path.to_path_buf())?;
        let newpath = join_path(buf, newname, &*self.root)?;

        let fid = self
            .fids
            .get_mut(&rename.fid)
            .ok_or_else(|| io::Error::from_raw_os_error(libc::EINVAL))?;

        fs::rename(&fid.path, &newpath)?;

        // TODO: figure out if the client expects |fid.path| to point to
        // the renamed path.
        fid.path = newpath.into_boxed_path();
        Ok(Rmessage::Rename)
    }

    fn readlink(&mut self, _readlink: &Treadlink) -> io::Result<Rmessage> {
        // symlinks are not allowed
        Err(io::Error::from_raw_os_error(libc::EACCES))
    }

    fn get_attr(&mut self, get_attr: &Tgetattr) -> io::Result<Rmessage> {
        let fid = self
            .fids
            .get_mut(&get_attr.fid)
            .ok_or_else(|| io::Error::from_raw_os_error(libc::EBADF))?;

        // Refresh the metadata since we were explicitly asked for it.
        fid.metadata = fs::metadata(&fid.path)?;

        Ok(Rmessage::GetAttr(Rgetattr {
            valid: P9_GETATTR_BASIC,
            qid: metadata_to_qid(&fid.metadata),
            mode: fid.metadata.st_mode(),
            uid: map_id_from_host(&self.uid_map, fid.metadata.st_uid()),
            gid: map_id_from_host(&self.gid_map, fid.metadata.st_gid()),
            nlink: fid.metadata.st_nlink(),
            rdev: fid.metadata.st_rdev(),
            size: fid.metadata.st_size(),
            blksize: fid.metadata.st_blksize(),
            blocks: fid.metadata.st_blocks(),
            atime_sec: fid.metadata.st_atime() as u64,
            atime_nsec: fid.metadata.st_atime_nsec() as u64,
            mtime_sec: fid.metadata.st_mtime() as u64,
            mtime_nsec: fid.metadata.st_mtime_nsec() as u64,
            ctime_sec: fid.metadata.st_ctime() as u64,
            ctime_nsec: fid.metadata.st_ctime_nsec() as u64,
            btime_sec: 0,
            btime_nsec: 0,
            gen: 0,
            data_version: 0,
        }))
    }

    fn set_attr(&mut self, set_attr: &Tsetattr) -> io::Result<Rmessage> {
        let blocked_ops = P9_SETATTR_MODE | P9_SETATTR_UID | P9_SETATTR_GID;
        if set_attr.valid & blocked_ops != 0 {
            return Err(io::Error::from_raw_os_error(libc::EPERM));
        }

        let fid = self
            .fids
            .get_mut(&set_attr.fid)
            .ok_or_else(|| io::Error::from_raw_os_error(libc::EBADF))?;
        let file = fs::OpenOptions::new().write(true).open(&fid.path)?;

        if set_attr.valid & P9_SETATTR_SIZE != 0 {
            file.set_len(set_attr.size)?;
        }

        if set_attr.valid & (P9_SETATTR_ATIME | P9_SETATTR_MTIME) != 0 {
            let times = [
                libc::timespec {
                    tv_sec: set_attr.atime_sec as _,
                    tv_nsec: if set_attr.valid & P9_SETATTR_ATIME == 0 {
                        libc::UTIME_OMIT
                    } else if set_attr.valid & P9_SETATTR_ATIME_SET == 0 {
                        libc::UTIME_NOW
                    } else {
                        set_attr.atime_nsec as _
                    },
                },
                libc::timespec {
                    tv_sec: set_attr.mtime_sec as _,
                    tv_nsec: if set_attr.valid & P9_SETATTR_MTIME == 0 {
                        libc::UTIME_OMIT
                    } else if set_attr.valid & P9_SETATTR_MTIME_SET == 0 {
                        libc::UTIME_NOW
                    } else {
                        set_attr.mtime_nsec as _
                    },
                },
            ];

            // Safe because file is valid and we have initialized times fully.
            let ret = unsafe { libc::futimens(file.as_raw_fd(), &times as *const libc::timespec) };
            if ret < 0 {
                return Err(io::Error::last_os_error());
            }
        }

        // The ctime would have been updated by any of the above operations so we only
        // need to change it if it was the only option given.
        if set_attr.valid & P9_SETATTR_CTIME != 0 && set_attr.valid & (!P9_SETATTR_CTIME) == 0 {
            // Setting -1 as the uid and gid will not actually change anything but will
            // still update the ctime.
            let ret = unsafe {
                libc::fchown(
                    file.as_raw_fd(),
                    libc::uid_t::max_value(),
                    libc::gid_t::max_value(),
                )
            };
            if ret < 0 {
                return Err(io::Error::last_os_error());
            }
        }

        Ok(Rmessage::SetAttr)
    }

    fn xattr_walk(&mut self, _xattr_walk: &Txattrwalk) -> io::Result<Rmessage> {
        Err(io::Error::from_raw_os_error(libc::EOPNOTSUPP))
    }

    fn xattr_create(&mut self, _xattr_create: &Txattrcreate) -> io::Result<Rmessage> {
        Err(io::Error::from_raw_os_error(libc::EOPNOTSUPP))
    }

    fn readdir(&mut self, readdir: &Treaddir) -> io::Result<Rmessage> {
        let fid = self
            .fids
            .get_mut(&readdir.fid)
            .ok_or_else(|| io::Error::from_raw_os_error(libc::EBADF))?;

        if !fid.metadata.is_dir() {
            return Err(io::Error::from_raw_os_error(libc::ENOTDIR));
        }

        // The p9 client implementation in the kernel doesn't fully read all the contents
        // of the directory.  This means that if some application performs a getdents()
        // call, followed by removing some files, followed by another getdents() call,
        // the offset that we get from the kernel is completely meaningless.  Instead
        // we fully read the contents of the directory here and only re-read the directory
        // if the offset we get from the client is 0.  Any other offset is served from the
        // directory entries in memory.  This ensures consistency even if the directory
        // changes in between Treaddir messages.
        if readdir.offset == 0 {
            let mut offset = 0;
            let iter = fs::read_dir(&fid.path)?;
            let dirents = iter.map(|item| -> io::Result<Dirent> {
                let entry = item?;

                let md = entry.metadata()?;
                let qid = metadata_to_qid(&md);

                let ty = if md.is_dir() {
                    libc::DT_DIR
                } else if md.is_file() {
                    libc::DT_REG
                } else {
                    libc::DT_UNKNOWN
                };

                let name = entry
                    .file_name()
                    .into_string()
                    .map_err(|_| io::Error::from_raw_os_error(libc::EINVAL))?;

                let mut out = Dirent {
                    qid: qid,
                    offset: 0, // set below
                    ty: ty,
                    name: name,
                };

                offset += out.byte_size() as u64;
                out.offset = offset;

                Ok(out)
            });

            // This is taking advantage of the fact that we can turn a Iterator of Result<T, E>
            // into a Result<FromIterator<T>, E> since Result implements FromIterator<Result<T, E>>.
            fid.dirents = Some(dirents.collect::<io::Result<Vec<Dirent>>>()?);
        }

        let mut entries = fid
            .dirents
            .as_ref()
            .ok_or_else(|| io::Error::from_raw_os_error(libc::EBADF))?
            .iter()
            .skip_while(|entry| entry.offset <= readdir.offset)
            .peekable();

        // Use an empty Rreaddir struct to figure out the maximum number of bytes that
        // can be returned.
        let header_size = Rframe {
            tag: 0,
            msg: Rmessage::Readdir(Rreaddir {
                data: Data(Vec::new()),
            }),
        }
        .byte_size();
        let count = min(self.msize - header_size, readdir.count);
        let mut cursor = Cursor::new(Vec::with_capacity(count as usize));

        loop {
            let byte_size = if let Some(entry) = entries.peek() {
                entry.byte_size() as usize
            } else {
                // No more entries.
                break;
            };

            if cursor.get_ref().capacity() - cursor.get_ref().len() < byte_size {
                // No more room in the buffer.
                break;
            }

            // Safe because we just checked that the iterator contains at least one more item.
            entries.next().unwrap().encode(&mut cursor)?;
        }

        Ok(Rmessage::Readdir(Rreaddir {
            data: Data(cursor.into_inner()),
        }))
    }

    fn fsync(&mut self, fsync: &Tfsync) -> io::Result<Rmessage> {
        let file = self
            .fids
            .get(&fsync.fid)
            .and_then(|fid| fid.file.as_ref())
            .ok_or_else(|| io::Error::from_raw_os_error(libc::EBADF))?;

        if fsync.datasync == 0 {
            file.sync_all()?;
        } else {
            file.sync_data()?;
        }
        Ok(Rmessage::Fsync)
    }

    fn lock(&mut self, _lock: &Tlock) -> io::Result<Rmessage> {
        // File locking is not supported.
        Err(io::Error::from_raw_os_error(libc::EOPNOTSUPP))
    }
    fn get_lock(&mut self, _get_lock: &Tgetlock) -> io::Result<Rmessage> {
        // File locking is not supported.
        Err(io::Error::from_raw_os_error(libc::EOPNOTSUPP))
    }

    fn link(&mut self, link: &Tlink) -> io::Result<Rmessage> {
        let newname = Path::new(&link.name);
        let buf = self
            .fids
            .get(&link.dfid)
            .map(|dfid| dfid.path.to_path_buf())
            .ok_or_else(|| io::Error::from_raw_os_error(libc::EBADF))?;
        let newpath = join_path(buf, newname, &*self.root)?;

        let path = self
            .fids
            .get(&link.fid)
            .map(|fid| &fid.path)
            .ok_or_else(|| io::Error::from_raw_os_error(libc::EBADF))?;

        fs::hard_link(path, &newpath)?;
        Ok(Rmessage::Link)
    }

    fn mkdir(&mut self, mkdir: &Tmkdir) -> io::Result<Rmessage> {
        let fid = self
            .fids
            .get(&mkdir.dfid)
            .ok_or_else(|| io::Error::from_raw_os_error(libc::EBADF))?;

        let name = Path::new(&mkdir.name);
        let newpath = join_path(fid.path.to_path_buf(), name, &*self.root)?;

        fs::DirBuilder::new()
            .recursive(false)
            .mode(mkdir.mode & 0o755)
            .create(&newpath)?;

        Ok(Rmessage::Mkdir(Rmkdir {
            qid: metadata_to_qid(&fs::metadata(&newpath)?),
        }))
    }

    fn rename_at(&mut self, rename_at: &Trenameat) -> io::Result<Rmessage> {
        let oldname = Path::new(&rename_at.oldname);
        let oldbuf = self
            .fids
            .get(&rename_at.olddirfid)
            .map(|dfid| dfid.path.to_path_buf())
            .ok_or_else(|| io::Error::from_raw_os_error(libc::EBADF))?;
        let oldpath = join_path(oldbuf, oldname, &*self.root)?;

        let newname = Path::new(&rename_at.newname);
        let newbuf = self
            .fids
            .get(&rename_at.newdirfid)
            .map(|dfid| dfid.path.to_path_buf())
            .ok_or_else(|| io::Error::from_raw_os_error(libc::EBADF))?;
        let newpath = join_path(newbuf, newname, &*self.root)?;

        fs::rename(&oldpath, &newpath)?;
        Ok(Rmessage::RenameAt)
    }

    fn unlink_at(&mut self, unlink_at: &Tunlinkat) -> io::Result<Rmessage> {
        let name = Path::new(&unlink_at.name);
        let buf = self
            .fids
            .get(&unlink_at.dirfd)
            .map(|fid| fid.path.to_path_buf())
            .ok_or_else(|| io::Error::from_raw_os_error(libc::EBADF))?;
        let path = join_path(buf, name, &*self.root)?;

        let md = fs::metadata(&path)?;
        if md.is_dir() && (unlink_at.flags & (libc::AT_REMOVEDIR as u32)) == 0 {
            return Err(io::Error::from_raw_os_error(libc::EISDIR));
        }

        if md.is_dir() {
            fs::remove_dir(&path)?;
        } else {
            fs::remove_file(&path)?;
        }

        Ok(Rmessage::UnlinkAt)
    }
}

#[cfg(test)]
mod tests {
    // Most of the server implementation is tested via integration tests.
    use super::*;

    #[test]
    fn path_joins() {
        let root = PathBuf::from("/a/b/c");
        let path = PathBuf::from("/a/b/c/d/e/f");

        assert_eq!(
            &join_path(path.clone(), "nested", &root).expect("normal"),
            Path::new("/a/b/c/d/e/f/nested")
        );

        let p1 = join_path(path.clone(), "..", &root).expect("parent 1");
        assert_eq!(&p1, Path::new("/a/b/c/d/e/"));

        let p2 = join_path(p1, "..", &root).expect("parent 2");
        assert_eq!(&p2, Path::new("/a/b/c/d/"));

        let p3 = join_path(p2, "..", &root).expect("parent 3");
        assert_eq!(&p3, Path::new("/a/b/c/"));

        let p4 = join_path(p3, "..", &root).expect("parent of root");
        assert_eq!(&p4, Path::new("/a/b/c/"));
    }

    #[test]
    fn invalid_joins() {
        let root = PathBuf::from("/a");
        let path = PathBuf::from("/a/b");

        join_path(path.clone(), ".", &root).expect_err("current directory");
        join_path(path.clone(), "c/d/e", &root).expect_err("too many components");
        join_path(path.clone(), "/c/d/e", &root).expect_err("absolute path");
    }
}
