// Copyright 2020 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 std::ffi::CStr;
use std::io;
use std::mem::size_of;
use std::os::unix::io::AsRawFd;

use data_model::DataInit;

use crate::syscall;

#[repr(C, packed)]
#[derive(Clone, Copy)]
struct LinuxDirent64 {
    d_ino: libc::ino64_t,
    d_off: libc::off64_t,
    d_reclen: libc::c_ushort,
    d_ty: libc::c_uchar,
}
unsafe impl DataInit for LinuxDirent64 {}

pub struct DirEntry<'r> {
    pub ino: libc::ino64_t,
    pub offset: u64,
    pub type_: u8,
    pub name: &'r CStr,
}

pub struct ReadDir<'d, D> {
    buf: [u8; 256],
    dir: &'d mut D,
    current: usize,
    end: usize,
}

impl<'d, D: AsRawFd> ReadDir<'d, D> {
    /// Return the next directory entry. This is implemented as a separate method rather than via
    /// the `Iterator` trait because rust doesn't currently support generic associated types.
    #[allow(clippy::should_implement_trait)]
    pub fn next(&mut self) -> Option<io::Result<DirEntry>> {
        if self.current >= self.end {
            let res = syscall!(unsafe {
                libc::syscall(
                    libc::SYS_getdents64,
                    self.dir.as_raw_fd(),
                    self.buf.as_mut_ptr() as *mut LinuxDirent64,
                    self.buf.len() as libc::c_int,
                )
            });
            match res {
                Ok(end) => {
                    self.current = 0;
                    self.end = end as usize;
                }
                Err(e) => return Some(Err(e)),
            }
        }

        let rem = &self.buf[self.current..self.end];
        if rem.is_empty() {
            return None;
        }

        // We only use debug asserts here because these values are coming from the kernel and we
        // trust them implicitly.
        debug_assert!(
            rem.len() >= size_of::<LinuxDirent64>(),
            "not enough space left in `rem`"
        );

        let (front, back) = rem.split_at(size_of::<LinuxDirent64>());

        let dirent64 =
            LinuxDirent64::from_slice(front).expect("unable to get LinuxDirent64 from slice");

        let namelen = dirent64.d_reclen as usize - size_of::<LinuxDirent64>();
        debug_assert!(namelen <= back.len(), "back is smaller than `namelen`");

        // The kernel will pad the name with additional nul bytes until it is 8-byte aligned so
        // we need to strip those off here.
        let name = strip_padding(&back[..namelen]);
        let entry = DirEntry {
            ino: dirent64.d_ino,
            offset: dirent64.d_off as u64,
            type_: dirent64.d_ty,
            name,
        };

        debug_assert!(
            rem.len() >= dirent64.d_reclen as usize,
            "rem is smaller than `d_reclen`"
        );
        self.current += dirent64.d_reclen as usize;
        Some(Ok(entry))
    }
}

pub fn read_dir<D: AsRawFd>(dir: &mut D, offset: libc::off64_t) -> io::Result<ReadDir<D>> {
    // Safe because this doesn't modify any memory and we check the return value.
    syscall!(unsafe { libc::lseek64(dir.as_raw_fd(), offset, libc::SEEK_SET) })?;

    Ok(ReadDir {
        buf: [0u8; 256],
        dir,
        current: 0,
        end: 0,
    })
}

// Like `CStr::from_bytes_with_nul` but strips any bytes after the first '\0'-byte. Panics if `b`
// doesn't contain any '\0' bytes.
fn strip_padding(b: &[u8]) -> &CStr {
    // It would be nice if we could use memchr here but that's locked behind an unstable gate.
    let pos = b
        .iter()
        .position(|&c| c == 0)
        .expect("`b` doesn't contain any nul bytes");

    // Safe because we are creating this string with the first nul-byte we found so we can
    // guarantee that it is nul-terminated and doesn't contain any interior nuls.
    unsafe { CStr::from_bytes_with_nul_unchecked(&b[..pos + 1]) }
}

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

    #[test]
    fn padded_cstrings() {
        assert_eq!(strip_padding(b".\0\0\0\0\0\0\0").to_bytes(), b".");
        assert_eq!(strip_padding(b"..\0\0\0\0\0\0").to_bytes(), b"..");
        assert_eq!(
            strip_padding(b"normal cstring\0").to_bytes(),
            b"normal cstring"
        );
        assert_eq!(strip_padding(b"\0\0\0\0").to_bytes(), b"");
        assert_eq!(
            strip_padding(b"interior\0nul bytes\0\0\0").to_bytes(),
            b"interior"
        );
    }

    #[test]
    #[should_panic(expected = "`b` doesn't contain any nul bytes")]
    fn no_nul_byte() {
        strip_padding(b"no nul bytes in string");
    }
}
