// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you 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.

//! Filesystem manipulation operations.

#[cfg(feature = "mesalock_sgx")]
use std::prelude::v1::*;

use crate::deps::sgx_aes_gcm_128bit_tag_t;
use crate::deps::sgx_key_128bit_t;
use crate::sgx_fs_inner as fs_imp;
use std::io::{self, Read, Seek, SeekFrom, Write};
use std::path::Path;

/// A reference to an open file on the filesystem.
///
/// An instance of a `File` can be read and/or written depending on what options
/// it was opened with. Files also implement [`Seek`] to alter the logical cursor
/// that the file contains internally.
///
/// Files are automatically closed when they go out of scope.
pub struct ProtectedFile {
    inner: fs_imp::SgxFile,
}

/// Options and flags which can be used to configure how a file is opened.
///
/// This builder exposes the ability to configure how a ProtectedFile is opened and
/// what operations are permitted on the open file. The ProtectedFile::open and
/// ProtectedFile::create methods are aliases for commonly used options using this
/// builder.
///
#[derive(Clone, Debug)]
pub struct OpenOptions(fs_imp::OpenOptions);

impl ProtectedFile {
    #[cfg(feature = "mesalock_sgx")]
    pub fn open<P: AsRef<Path>>(path: P) -> io::Result<ProtectedFile> {
        OpenOptions::default().read(true).open(path.as_ref())
    }

    #[cfg(feature = "mesalock_sgx")]
    pub fn create<P: AsRef<Path>>(path: P) -> io::Result<ProtectedFile> {
        OpenOptions::default().write(true).open(path.as_ref())
    }

    pub fn open_ex<P: AsRef<Path>>(path: P, key: &sgx_key_128bit_t) -> io::Result<ProtectedFile> {
        OpenOptions::default()
            .read(true)
            .open_ex(path.as_ref(), key)
    }

    pub fn append_ex<P: AsRef<Path>>(path: P, key: &sgx_key_128bit_t) -> io::Result<ProtectedFile> {
        OpenOptions::default()
            .append(true)
            .open_ex(path.as_ref(), key)
    }

    pub fn create_ex<P: AsRef<Path>>(path: P, key: &sgx_key_128bit_t) -> io::Result<ProtectedFile> {
        OpenOptions::default()
            .write(true)
            .open_ex(path.as_ref(), key)
    }

    pub fn is_eof(&self) -> bool {
        self.inner.is_eof()
    }

    pub fn clearerr(&self) {
        self.inner.clearerr()
    }

    pub fn clear_cache(&self) -> io::Result<()> {
        self.inner.clear_cache()
    }

    pub fn current_meta_gmac(&self) -> io::Result<sgx_aes_gcm_128bit_tag_t> {
        let mut meta_gmac = sgx_aes_gcm_128bit_tag_t::default();
        self.inner.get_current_meta_gmac(&mut meta_gmac)?;
        Ok(meta_gmac)
    }

    pub fn rename_meta<P: AsRef<Path>, Q: AsRef<Path>>(
        &self,
        old_name: P,
        new_name: Q,
    ) -> io::Result<()> {
        self.inner.rename_meta(old_name.as_ref(), new_name.as_ref())
    }

    pub fn read_at(&self, off: usize, dst: &mut [u8]) -> io::Result<usize> {
        let pre = self.inner.seek(SeekFrom::Current(0))?;
        self.inner.seek(SeekFrom::Start(off as u64))?;

        let size = match self.inner.read(dst) {
            Ok(size) => size,
            Err(e) => {
                self.inner.seek(SeekFrom::Start(pre))?;
                return Err(e);
            }
        };

        self.inner.seek(SeekFrom::Start(pre))?;
        Ok(size)
    }
}

impl Read for ProtectedFile {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        self.inner.read(buf)
    }
}

impl Write for ProtectedFile {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        self.inner.write(buf)
    }
    fn flush(&mut self) -> io::Result<()> {
        self.inner.flush()
    }
}

impl Seek for ProtectedFile {
    fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {
        self.inner.seek(pos)
    }
}

impl<'a> Read for &'a ProtectedFile {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        self.inner.read(buf)
    }
}

impl<'a> Write for &'a ProtectedFile {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        self.inner.write(buf)
    }
    fn flush(&mut self) -> io::Result<()> {
        self.inner.flush()
    }
}

impl<'a> Seek for &'a ProtectedFile {
    fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {
        self.inner.seek(pos)
    }
}

impl OpenOptions {
    /// Creates a blank new set of options ready for configuration.
    ///
    /// All options are initially set to `false`.
    ///
    pub fn default() -> OpenOptions {
        OpenOptions(fs_imp::OpenOptions::new())
    }

    /// Sets the option for read access.
    ///
    /// This option, when true, will indicate that the file should be
    /// `read`-able if opened.
    ///
    pub fn read(&mut self, read: bool) -> &mut OpenOptions {
        self.0.read(read);
        self
    }

    /// Sets the option for write access.
    ///
    /// This option, when true, will indicate that the file should be
    /// `write`-able if opened.
    ///
    pub fn write(&mut self, write: bool) -> &mut OpenOptions {
        self.0.write(write);
        self
    }

    /// Sets the option for the append mode.
    ///
    /// This option, when true, means that writes will append to a file instead
    /// of overwriting previous contents.
    /// Note that setting `.write(true).append(true)` has the same effect as
    /// setting only `.append(true)`.
    ///
    /// For most filesystems, the operating system guarantees that all writes are
    /// atomic: no writes get mangled because another process writes at the same
    /// time.
    ///
    /// One maybe obvious note when using append-mode: make sure that all data
    /// that belongs together is written to the file in one operation. This
    /// can be done by concatenating strings before passing them to `write()`,
    /// or using a buffered writer (with a buffer of adequate size),
    /// and calling `flush()` when the message is complete.
    ///
    /// If a file is opened with both read and append access, beware that after
    /// opening, and after every write, the position for reading may be set at the
    /// end of the file. So, before writing, save the current position (using
    /// `seek(SeekFrom::Current(0))`, and restore it before the next read.
    ///
    pub fn append(&mut self, append: bool) -> &mut OpenOptions {
        self.0.append(append);
        self
    }

    /// Sets the option for update a previous file.
    pub fn update(&mut self, update: bool) -> &mut OpenOptions {
        self.0.update(update);
        self
    }

    /// Sets the option for binary a file.
    pub fn binary(&mut self, binary: bool) -> &mut OpenOptions {
        self.0.binary(binary);
        self
    }

    /// Opens a file at `path` with the options specified by `self`.
    pub fn open<P: AsRef<Path>>(&self, path: P) -> io::Result<ProtectedFile> {
        self._open(path.as_ref())
    }

    pub fn open_ex<P: AsRef<Path>>(
        &self,
        path: P,
        key: &sgx_key_128bit_t,
    ) -> io::Result<ProtectedFile> {
        self._open_ex(path.as_ref(), key)
    }

    fn _open(&self, path: &Path) -> io::Result<ProtectedFile> {
        let inner = fs_imp::SgxFile::open(path, &self.0)?;
        Ok(ProtectedFile { inner })
    }

    fn _open_ex(&self, path: &Path, key: &sgx_key_128bit_t) -> io::Result<ProtectedFile> {
        let inner = fs_imp::SgxFile::open_ex(path, &self.0, key)?;
        Ok(ProtectedFile { inner })
    }
}

pub fn remove_protected_file<P: AsRef<Path>>(path: P) -> io::Result<()> {
    fs_imp::remove(path.as_ref())
}

#[cfg(feature = "mesalock_sgx")]
pub fn export_auto_key<P: AsRef<Path>>(path: P) -> io::Result<sgx_key_128bit_t> {
    fs_imp::export_auto_key(path.as_ref())
}

#[cfg(feature = "mesalock_sgx")]
pub fn import_auto_key<P: AsRef<Path>>(path: P, key: &sgx_key_128bit_t) -> io::Result<()> {
    fs_imp::import_auto_key(path.as_ref(), key)
}

#[cfg(test)]
mod tests {
    use crate::remove_protected_file;
    use crate::ProtectedFile;
    use rand_core::RngCore;
    use std::io::{Read, Write};

    #[test]
    pub fn test_sgxfs() {
        let key = [90u8; 16];

        let mut write_data: [u8; 16] = [0; 16];
        let mut read_data: [u8; 16] = [0; 16];
        let write_size;
        let read_size;
        {
            let mut rng = rdrand::RdRand::new().unwrap();
            rng.fill_bytes(&mut write_data);

            let opt = ProtectedFile::create_ex("sgx_file", &key);
            assert_eq!(opt.is_ok(), true);
            let mut file = opt.unwrap();

            let result = file.write(&write_data);
            assert_eq!(result.is_ok(), true);
            write_size = result.unwrap();
        }

        {
            let opt = ProtectedFile::open_ex("sgx_file", &key);
            assert_eq!(opt.is_ok(), true);
            let mut file = opt.unwrap();

            let result = file.read(&mut read_data);
            assert_eq!(result.is_ok(), true);
            read_size = result.unwrap();
        }

        let result = remove_protected_file("sgx_file");
        assert_eq!(result.is_ok(), true);

        assert_eq!(write_data, read_data);
        assert_eq!(write_size, read_size);

        {
            let opt = ProtectedFile::open_ex("/", &key);
            assert_eq!(opt.is_err(), true);
            let opt = ProtectedFile::open_ex(".", &key);
            assert_eq!(opt.is_err(), true);
            let opt = ProtectedFile::open_ex("..", &key);
            assert_eq!(opt.is_err(), true);
            let opt = ProtectedFile::open_ex("?", &key);
            assert_eq!(opt.is_err(), true);
        }
        {
            let opt = ProtectedFile::create_ex("/", &key);
            assert_eq!(opt.is_err(), true);
        }
        {
            let opt = ProtectedFile::create_ex("/proc/100", &key);
            assert_eq!(opt.is_err(), true);
            let opt = ProtectedFile::create_ex(".", &key);
            assert_eq!(opt.is_err(), true);
            let opt = ProtectedFile::create_ex("..", &key);
            assert_eq!(opt.is_err(), true);
        }
    }
}
