// Copyright 2021 The Fuchsia 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 crate::fs::*;
use crate::logging::not_implemented;
use crate::task::*;
use crate::types::as_any::AsAny;
use crate::types::*;
use zerocopy::AsBytes;

/// The version of selinux_status_t this kernel implements.
const SELINUX_STATUS_VERSION: u32 = 1;

struct SeLinuxFs;
impl FileSystemOps for SeLinuxFs {
    fn statfs(&self, _fs: &FileSystem) -> Result<statfs, Errno> {
        Ok(statfs { f_type: SELINUX_MAGIC as i64, ..Default::default() })
    }
}

impl SeLinuxFs {
    fn new() -> Result<FileSystemHandle, Errno> {
        let fs = FileSystem::new_with_permanent_entries(SeLinuxFs);
        fs.set_root(ROMemoryDirectory);
        let root = fs.root();
        root.add_node_ops(b"load", mode!(IFREG, 0600), SeLinuxNode::new(|| Ok(SeLoad)))?;
        root.add_node_ops(b"enforce", mode!(IFREG, 0644), SeLinuxNode::new(|| Ok(SeEnforce)))?;
        root.add_node_ops(
            b"checkreqprot",
            mode!(IFREG, 0644),
            SeLinuxNode::new(|| Ok(SeCheckReqProt)),
        )?;
        root.add_node_ops(
            b"deny_unknown",
            mode!(IFREG, 0444),
            // Allow all unknown object classes/permissions.
            ByteVecFile::new(b"0:0\n".to_vec()),
        )?;

        // The status file needs to be mmap-able, so use a VMO-backed file.
        // When the selinux state changes in the future, the way to update this data (and
        // communicate updates with userspace) is to use the
        // ["seqlock"](https://en.wikipedia.org/wiki/Seqlock) technique.
        root.add_node_ops(
            b"status",
            mode!(IFREG, 0444),
            VmoFileNode::from_bytes(
                selinux_status_t { version: SELINUX_STATUS_VERSION, ..Default::default() }
                    .as_bytes(),
            )?,
        )?;

        Ok(fs)
    }
}

pub struct SeLinuxNode<F, O>
where
    F: Fn() -> Result<O, Errno>,
    O: FileOps,
{
    open: F,
}
impl<F, O> SeLinuxNode<F, O>
where
    F: Fn() -> Result<O, Errno> + Send + Sync,
    O: FileOps + 'static,
{
    pub fn new(open: F) -> SeLinuxNode<F, O> {
        Self { open }
    }
}
impl<F, O> FsNodeOps for SeLinuxNode<F, O>
where
    F: Fn() -> Result<O, Errno> + Send + Sync + 'static,
    O: FileOps + 'static,
{
    fn open(&self, _node: &FsNode, _flags: OpenFlags) -> Result<Box<dyn FileOps>, Errno> {
        Ok(Box::new((self.open)()?))
    }

    fn truncate(&self, _node: &FsNode, _length: u64) -> Result<(), Errno> {
        // TODO(tbodt): Is this right? This is the minimum to handle O_TRUNC
        Ok(())
    }
}

trait SeLinuxFile {
    fn write(&self, data: Vec<u8>) -> Result<(), Errno>;
    fn read(&self) -> Result<Vec<u8>, Errno> {
        error!(ENOSYS)
    }
}

impl<T: SeLinuxFile + Send + Sync + AsAny + 'static> FileOps for T {
    fileops_impl_seekable!();
    fileops_impl_nonblocking!();

    fn write_at(
        &self,
        _file: &FileObject,
        current_task: &CurrentTask,
        offset: usize,
        data: &[UserBuffer],
    ) -> Result<usize, Errno> {
        if offset != 0 {
            return error!(EINVAL);
        }
        let size = UserBuffer::get_total_length(data)?;
        let mut buf = vec![0u8; size];
        current_task.mm.read_all(&data, &mut buf)?;
        self.write(buf)?;
        Ok(size)
    }

    fn read_at(
        &self,
        _file: &FileObject,
        current_task: &CurrentTask,
        _offset: usize,
        buffer: &[UserBuffer],
    ) -> Result<usize, Errno> {
        let data = self.read()?;
        current_task.mm.write_all(buffer, &data)
    }
}

/// The C-style struct exposed to userspace by the /sys/fs/selinux/status file.
/// Defined here (instead of imported through bindgen) as selinux headers are not exposed through
/// kernel uapi headers.
#[derive(Debug, Copy, Clone, AsBytes, Default)]
#[repr(C, packed)]
struct selinux_status_t {
    /// Version number of this structure (1).
    version: u32,
    /// Sequence number. See [seqlock](https://en.wikipedia.org/wiki/Seqlock).
    sequence: u32,
    /// `0` means permissive mode, `1` means enforcing mode.
    enforcing: u32,
    /// The number of times the selinux policy has been reloaded.
    policyload: u32,
    /// `0` means allow and `1` means deny unknown object classes/permissions.
    deny_unknown: u32,
}

struct SeLoad;
impl SeLinuxFile for SeLoad {
    fn write(&self, data: Vec<u8>) -> Result<(), Errno> {
        not_implemented!("got selinux policy, length {}, ignoring", data.len());
        Ok(())
    }
}

struct SeEnforce;
impl SeLinuxFile for SeEnforce {
    fn write(&self, data: Vec<u8>) -> Result<(), Errno> {
        let enforce = parse_int(&data)?;
        not_implemented!("selinux setenforce: {}", enforce);
        Ok(())
    }

    fn read(&self) -> Result<Vec<u8>, Errno> {
        Ok(b"0\n".to_vec())
    }
}

struct SeCheckReqProt;
impl SeLinuxFile for SeCheckReqProt {
    fn write(&self, data: Vec<u8>) -> Result<(), Errno> {
        let checkreqprot = parse_int(&data)?;
        not_implemented!("selinux checkreqprot: {}", checkreqprot);
        Ok(())
    }
}

fn parse_int(buf: &[u8]) -> Result<u32, Errno> {
    let i = buf.iter().position(|c| !char::from(*c).is_digit(10)).unwrap_or(buf.len());
    std::str::from_utf8(&buf[..i]).unwrap().parse::<u32>().map_err(|_| errno!(EINVAL))
}

pub fn selinux_fs(kern: &Kernel) -> &FileSystemHandle {
    kern.selinux_fs.get_or_init(|| SeLinuxFs::new().expect("failed to construct selinuxfs"))
}
