/*
 * Copyright (C) 2021 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

use anyhow::Result;
use std::collections::BTreeMap;
use std::convert::TryFrom;
use std::ffi::CStr;
use std::fs::OpenOptions;
use std::io;
use std::mem::MaybeUninit;
use std::option::Option;
use std::os::unix::io::AsRawFd;
use std::path::Path;
use std::time::Duration;

use fuse::filesystem::{Context, DirEntry, DirectoryIterator, Entry, FileSystem, ZeroCopyWriter};
use fuse::mount::MountOption;

use crate::common::{divide_roundup, COMMON_PAGE_SIZE};
use crate::fsverity::FsverityChunkedFileReader;
use crate::reader::{ChunkedFileReader, ReadOnlyDataByChunk};

// We're reading the backing file by chunk, so setting the block size to be the same.
const BLOCK_SIZE: usize = COMMON_PAGE_SIZE as usize;

const DEFAULT_METADATA_TIMEOUT: std::time::Duration = Duration::from_secs(5);

pub type Inode = u64;
type Handle = u64;

// A debug only type where everything are stored as local files.
type FileBackedFsverityChunkedFileReader =
    FsverityChunkedFileReader<ChunkedFileReader, ChunkedFileReader>;

pub enum FileConfig {
    LocalVerifiedFile(FileBackedFsverityChunkedFileReader, u64),
    LocalUnverifiedFile(ChunkedFileReader, u64),
}

struct AuthFs {
    /// Store `FileConfig`s using the `Inode` number as the search index.
    ///
    /// For further optimization to minimize the search cost, since Inode is integer, we may
    /// consider storing them in a Vec if we can guarantee that the numbers are small and
    /// consecutive.
    file_pool: BTreeMap<Inode, FileConfig>,

    /// Maximum bytes in the write transaction to the FUSE device. This limits the maximum size to
    /// a read request (including FUSE protocol overhead).
    max_write: u32,
}

impl AuthFs {
    pub fn new(file_pool: BTreeMap<Inode, FileConfig>, max_write: u32) -> AuthFs {
        AuthFs { file_pool, max_write }
    }

    fn get_file_config(&self, inode: &Inode) -> io::Result<&FileConfig> {
        self.file_pool.get(&inode).ok_or_else(|| io::Error::from_raw_os_error(libc::ENOENT))
    }
}

fn check_access_mode(flags: u32, mode: libc::c_int) -> io::Result<()> {
    if (flags & libc::O_ACCMODE as u32) == mode as u32 {
        Ok(())
    } else {
        Err(io::Error::from_raw_os_error(libc::EACCES))
    }
}

cfg_if::cfg_if! {
    if #[cfg(all(target_arch = "aarch64", target_pointer_width = "64"))] {
        fn blk_size() -> libc::c_int { BLOCK_SIZE as libc::c_int }
    } else {
        fn blk_size() -> libc::c_long { BLOCK_SIZE as libc::c_long }
    }
}

fn create_stat(ino: libc::ino_t, file_size: u64) -> io::Result<libc::stat64> {
    let mut st = unsafe { MaybeUninit::<libc::stat64>::zeroed().assume_init() };

    st.st_ino = ino;
    st.st_mode = libc::S_IFREG | libc::S_IRUSR | libc::S_IRGRP | libc::S_IROTH;
    st.st_dev = 0;
    st.st_nlink = 1;
    st.st_uid = 0;
    st.st_gid = 0;
    st.st_rdev = 0;
    st.st_size = libc::off64_t::try_from(file_size)
        .map_err(|_| io::Error::from_raw_os_error(libc::EFBIG))?;
    st.st_blksize = blk_size();
    // Per man stat(2), st_blocks is "Number of 512B blocks allocated".
    st.st_blocks = libc::c_longlong::try_from(divide_roundup(file_size, 512))
        .map_err(|_| io::Error::from_raw_os_error(libc::EFBIG))?;
    Ok(st)
}

/// An iterator that generates (offset, size) for a chunked read operation, where offset is the
/// global file offset, and size is the amount of read from the offset.
struct ChunkReadIter {
    remaining: usize,
    offset: u64,
}

impl ChunkReadIter {
    pub fn new(remaining: usize, offset: u64) -> Self {
        ChunkReadIter { remaining, offset }
    }
}

impl Iterator for ChunkReadIter {
    type Item = (u64, usize);

    fn next(&mut self) -> Option<Self::Item> {
        if self.remaining == 0 {
            return None;
        }
        let chunk_data_size =
            std::cmp::min(self.remaining, BLOCK_SIZE - (self.offset % BLOCK_SIZE as u64) as usize);
        let retval = (self.offset, chunk_data_size);
        self.offset += chunk_data_size as u64;
        self.remaining = self.remaining.saturating_sub(chunk_data_size);
        Some(retval)
    }
}

fn offset_to_chunk_index(offset: u64) -> u64 {
    offset / BLOCK_SIZE as u64
}

fn read_chunks<W: io::Write, T: ReadOnlyDataByChunk>(
    mut w: W,
    file: &T,
    file_size: u64,
    offset: u64,
    size: u32,
) -> io::Result<usize> {
    let remaining = file_size.saturating_sub(offset);
    let size_to_read = std::cmp::min(size as usize, remaining as usize);
    let total = ChunkReadIter::new(size_to_read, offset).try_fold(
        0,
        |total, (current_offset, planned_data_size)| {
            // TODO(victorhsieh): There might be a non-trivial way to avoid this copy. For example,
            // instead of accepting a buffer, the writer could expose the final destination buffer
            // for the reader to write to. It might not be generally applicable though, e.g. with
            // virtio transport, the buffer may not be continuous.
            let mut buf = [0u8; BLOCK_SIZE];
            let read_size = file.read_chunk(offset_to_chunk_index(current_offset), &mut buf)?;
            if read_size < planned_data_size {
                return Err(io::Error::from_raw_os_error(libc::ENODATA));
            }

            let begin = (current_offset % BLOCK_SIZE as u64) as usize;
            let end = begin + planned_data_size;
            let s = w.write(&buf[begin..end])?;
            if s != planned_data_size {
                return Err(io::Error::from_raw_os_error(libc::EIO));
            }
            Ok(total + s)
        },
    )?;

    Ok(total)
}

// No need to support enumerating directory entries.
struct EmptyDirectoryIterator {}

impl DirectoryIterator for EmptyDirectoryIterator {
    fn next(&mut self) -> Option<DirEntry> {
        None
    }
}

impl FileSystem for AuthFs {
    type Inode = Inode;
    type Handle = Handle;
    type DirIter = EmptyDirectoryIterator;

    fn max_buffer_size(&self) -> u32 {
        self.max_write
    }

    fn lookup(&self, _ctx: Context, _parent: Inode, name: &CStr) -> io::Result<Entry> {
        // Only accept file name that looks like an integrer. Files in the pool are simply exposed
        // by their inode number. Also, there is currently no directory structure.
        let num = name.to_str().map_err(|_| io::Error::from_raw_os_error(libc::EINVAL))?;
        // Normally, `lookup` is required to increase a reference count for the inode (while
        // `forget` will decrease it). It is not necessary here since the files are configured to
        // be static.
        let inode = num.parse::<Inode>().map_err(|_| io::Error::from_raw_os_error(libc::ENOENT))?;
        let st = match self.get_file_config(&inode)? {
            FileConfig::LocalVerifiedFile(_, file_size)
            | FileConfig::LocalUnverifiedFile(_, file_size) => create_stat(inode, *file_size)?,
        };
        Ok(Entry {
            inode,
            generation: 0,
            attr: st,
            entry_timeout: DEFAULT_METADATA_TIMEOUT,
            attr_timeout: DEFAULT_METADATA_TIMEOUT,
        })
    }

    fn getattr(
        &self,
        _ctx: Context,
        inode: Inode,
        _handle: Option<Handle>,
    ) -> io::Result<(libc::stat64, Duration)> {
        Ok((
            match self.get_file_config(&inode)? {
                FileConfig::LocalVerifiedFile(_, file_size)
                | FileConfig::LocalUnverifiedFile(_, file_size) => create_stat(inode, *file_size)?,
            },
            DEFAULT_METADATA_TIMEOUT,
        ))
    }

    fn open(
        &self,
        _ctx: Context,
        inode: Self::Inode,
        flags: u32,
    ) -> io::Result<(Option<Self::Handle>, fuse::sys::OpenOptions)> {
        // Since file handle is not really used in later operations (which use Inode directly),
        // return None as the handle..
        match self.get_file_config(&inode)? {
            FileConfig::LocalVerifiedFile(_, _) => {
                check_access_mode(flags, libc::O_RDONLY)?;
                // Once verified, and only if verified, the file content can be cached. This is not
                // really needed for a local file, but is the behavior of RemoteVerifiedFile later.
                Ok((None, fuse::sys::OpenOptions::KEEP_CACHE))
            }
            FileConfig::LocalUnverifiedFile(_, _) => {
                check_access_mode(flags, libc::O_RDONLY)?;
                // Do not cache the content. This type of file is supposed to be verified using
                // dm-verity. The filesystem mount over dm-verity already is already cached, so use
                // direct I/O here to avoid double cache.
                Ok((None, fuse::sys::OpenOptions::DIRECT_IO))
            }
        }
    }

    fn read<W: io::Write + ZeroCopyWriter>(
        &self,
        _ctx: Context,
        inode: Inode,
        _handle: Handle,
        w: W,
        size: u32,
        offset: u64,
        _lock_owner: Option<u64>,
        _flags: u32,
    ) -> io::Result<usize> {
        match self.get_file_config(&inode)? {
            FileConfig::LocalVerifiedFile(file, file_size) => {
                read_chunks(w, file, *file_size, offset, size)
            }
            FileConfig::LocalUnverifiedFile(file, file_size) => {
                read_chunks(w, file, *file_size, offset, size)
            }
        }
    }
}

/// Mount and start the FUSE instance. This requires CAP_SYS_ADMIN.
pub fn loop_forever(
    file_pool: BTreeMap<Inode, FileConfig>,
    mountpoint: &Path,
) -> Result<(), fuse::Error> {
    let max_read: u32 = 65536;
    let max_write: u32 = 65536;
    let dev_fuse = OpenOptions::new()
        .read(true)
        .write(true)
        .open("/dev/fuse")
        .expect("Failed to open /dev/fuse");

    fuse::mount(
        mountpoint,
        "authfs",
        libc::MS_NOSUID | libc::MS_NODEV,
        &[
            MountOption::FD(dev_fuse.as_raw_fd()),
            MountOption::RootMode(libc::S_IFDIR | libc::S_IXUSR | libc::S_IXGRP | libc::S_IXOTH),
            MountOption::AllowOther,
            MountOption::UserId(0),
            MountOption::GroupId(0),
            MountOption::MaxRead(max_read),
        ],
    )
    .expect("Failed to mount fuse");

    fuse::worker::start_message_loop(
        dev_fuse,
        max_write,
        max_read,
        AuthFs::new(file_pool, max_write),
    )
}

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

    fn collect_chunk_read_iter(remaining: usize, offset: u64) -> Vec<(u64, usize)> {
        ChunkReadIter::new(remaining, offset).collect::<Vec<_>>()
    }

    #[test]
    fn test_chunk_read_iter() {
        assert_eq!(collect_chunk_read_iter(4096, 0), [(0, 4096)]);
        assert_eq!(collect_chunk_read_iter(8192, 0), [(0, 4096), (4096, 4096)]);
        assert_eq!(collect_chunk_read_iter(8192, 4096), [(4096, 4096), (8192, 4096)]);

        assert_eq!(
            collect_chunk_read_iter(16384, 1),
            [(1, 4095), (4096, 4096), (8192, 4096), (12288, 4096), (16384, 1)]
        );

        assert_eq!(collect_chunk_read_iter(0, 0), []);
        assert_eq!(collect_chunk_read_iter(0, 100), []);
    }
}
