// 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::root_dir::RootDir,
    anyhow::Context as _,
    async_trait::async_trait,
    fidl::{endpoints::ServerEnd, HandleBased as _},
    fidl_fuchsia_io as fio,
    fuchsia_syslog::fx_log_err,
    fuchsia_zircon as zx,
    once_cell::sync::OnceCell,
    std::sync::Arc,
    vfs::{
        common::send_on_open_with_error, directory::entry::EntryInfo,
        execution_scope::ExecutionScope, path::Path as VfsPath,
    },
};

/// Location of MetaFile contents within a meta.far
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub(crate) struct MetaFileLocation {
    pub(crate) offset: u64,
    pub(crate) length: u64,
}

pub(crate) struct MetaFile {
    root_dir: Arc<RootDir>,
    location: MetaFileLocation,
    vmo: OnceCell<zx::Vmo>,
}

impl MetaFile {
    pub(crate) fn new(root_dir: Arc<RootDir>, location: MetaFileLocation) -> Self {
        MetaFile { root_dir, location, vmo: OnceCell::new() }
    }

    async fn vmo(&self) -> Result<&zx::Vmo, anyhow::Error> {
        Ok(if let Some(vmo) = self.vmo.get() {
            vmo
        } else {
            let far_vmo = self.root_dir.meta_far_vmo().await.context("getting far vmo")?;
            // The FAR spec requires 4 KiB alignment of content chunks [1], so offset will
            // always be page-aligned, because pages are required [2] to be a power of 2 and at
            // least 4 KiB.
            // [1] https://fuchsia.dev/fuchsia-src/concepts/source_code/archive_format#content_chunk
            // [2] https://fuchsia.dev/fuchsia-src/reference/syscalls/system_get_page_size
            // TODO(fxbug.dev/82006) Need to manually zero the end of the VMO if
            // zx_system_get_page_size() > 4K.
            assert_eq!(zx::system_get_page_size(), 4096);
            let vmo = far_vmo
                .create_child(
                    zx::VmoChildOptions::SNAPSHOT_AT_LEAST_ON_WRITE | zx::VmoChildOptions::NO_WRITE,
                    self.location.offset,
                    self.location.length,
                )
                .context("creating MetaFile VMO")?;
            self.vmo.get_or_init(|| vmo)
        })
    }
}

impl vfs::directory::entry::DirectoryEntry for MetaFile {
    fn open(
        self: Arc<Self>,
        scope: ExecutionScope,
        flags: fio::OpenFlags,
        _mode: u32,
        path: VfsPath,
        server_end: ServerEnd<fio::NodeMarker>,
    ) {
        if !path.is_empty() {
            let () = send_on_open_with_error(flags, server_end, zx::Status::NOT_DIR);
            return;
        }

        if flags.intersects(
            fio::OpenFlags::RIGHT_WRITABLE
                | fio::OpenFlags::RIGHT_EXECUTABLE
                | fio::OpenFlags::CREATE
                | fio::OpenFlags::CREATE_IF_ABSENT
                | fio::OpenFlags::TRUNCATE
                | fio::OpenFlags::APPEND,
        ) {
            let () = send_on_open_with_error(flags, server_end, zx::Status::NOT_SUPPORTED);
            return;
        }

        let () = vfs::file::connection::io1::FileConnection::<Self>::create_connection(
            scope.clone(),
            self,
            flags,
            server_end,
            // readable/writable do not override what's set in flags, they merely tell the
            // FileConnection that it's valid to open the file readable/writable.
            true,  /*=readable*/
            false, /*=writable*/
            false, /*=executable*/
        );
    }

    fn entry_info(&self) -> vfs::directory::entry::EntryInfo {
        EntryInfo::new(fio::INO_UNKNOWN, fio::DirentType::File)
    }
}

#[async_trait]
impl vfs::file::File for MetaFile {
    async fn open(&self, _flags: fio::OpenFlags) -> Result<(), zx::Status> {
        Ok(())
    }

    async fn read_at(&self, offset_chunk: u64, buffer: &mut [u8]) -> Result<u64, zx::Status> {
        let offset_chunk = std::cmp::min(offset_chunk, self.location.length);
        let offset_far = offset_chunk + self.location.offset;
        let count = std::cmp::min(
            crate::usize_to_u64_safe(buffer.len()),
            self.location.length - offset_chunk,
        );
        let bytes = self
            .root_dir
            .meta_far
            .read_at(count, offset_far)
            .await
            .map_err(|e: fidl::Error| {
                fx_log_err!("meta.far read_at fidl error: {:#}", e);
                zx::Status::INTERNAL
            })?
            .map_err(zx::Status::from_raw)
            .map_err(|e: zx::Status| {
                fx_log_err!("meta.far read_at protocol error: {:#}", e);
                e
            })?;
        let () = buffer[..bytes.len()].copy_from_slice(&bytes);
        Ok(crate::usize_to_u64_safe(bytes.len()))
    }

    async fn write_at(&self, _offset: u64, _content: &[u8]) -> Result<u64, zx::Status> {
        Err(zx::Status::NOT_SUPPORTED)
    }

    async fn append(&self, _content: &[u8]) -> Result<(u64, u64), zx::Status> {
        Err(zx::Status::NOT_SUPPORTED)
    }

    async fn truncate(&self, _length: u64) -> Result<(), zx::Status> {
        Err(zx::Status::NOT_SUPPORTED)
    }

    async fn get_buffer(
        &self,
        flags: fio::VmoFlags,
    ) -> Result<fidl_fuchsia_mem::Buffer, zx::Status> {
        if flags.intersects(
            fio::VmoFlags::WRITE | fio::VmoFlags::EXECUTE | fio::VmoFlags::SHARED_BUFFER,
        ) {
            return Err(zx::Status::NOT_SUPPORTED);
        }

        let vmo = self.vmo().await.map_err(|e: anyhow::Error| {
            fx_log_err!("Failed to get MetaFile VMO during get_buffer: {:#}", e);
            zx::Status::INTERNAL
        })?;

        if flags.contains(fio::VmoFlags::PRIVATE_CLONE) {
            let vmo = vmo
                .create_child(
                    zx::VmoChildOptions::SNAPSHOT_AT_LEAST_ON_WRITE | zx::VmoChildOptions::NO_WRITE,
                    0, /*offset*/
                    self.location.length,
                )
                .map_err(|e: zx::Status| {
                    fx_log_err!("Failed to create private child VMO during get_buffer: {:#}", e);
                    e
                })?;
            Ok(fidl_fuchsia_mem::Buffer { vmo, size: self.location.length })
        } else {
            let rights = zx::Rights::BASIC
                | zx::Rights::MAP
                | zx::Rights::PROPERTY
                | if flags.contains(fio::VmoFlags::READ) {
                    zx::Rights::READ
                } else {
                    zx::Rights::NONE
                };
            let vmo = vmo.duplicate_handle(rights).map_err(|e: zx::Status| {
                fx_log_err!("Failed to clone VMO handle during get_buffer: {:#}", e);
                e
            })?;
            Ok(fidl_fuchsia_mem::Buffer { vmo, size: self.location.length })
        }
    }

    async fn get_size(&self) -> Result<u64, zx::Status> {
        Ok(self.location.length)
    }

    async fn get_attrs(&self) -> Result<fio::NodeAttributes, zx::Status> {
        Ok(fio::NodeAttributes {
            mode: fio::MODE_TYPE_FILE
                | vfs::common::rights_to_posix_mode_bits(
                    true,  // read
                    false, // write
                    false, // execute
                ),
            id: 1,
            content_size: self.location.length,
            storage_size: self.location.length,
            link_count: 1,
            creation_time: 0,
            modification_time: 0,
        })
    }

    async fn set_attrs(
        &self,
        _flags: fio::NodeAttributeFlags,
        _attrs: fio::NodeAttributes,
    ) -> Result<(), zx::Status> {
        Err(zx::Status::NOT_SUPPORTED)
    }

    async fn close(&self) -> Result<(), zx::Status> {
        Ok(())
    }

    async fn sync(&self) -> Result<(), zx::Status> {
        Err(zx::Status::NOT_SUPPORTED)
    }
}

#[cfg(test)]
mod tests {
    use {
        super::*,
        assert_matches::assert_matches,
        fidl::{endpoints::Proxy as _, AsHandleRef as _},
        fuchsia_pkg_testing::{blobfs::Fake as FakeBlobfs, PackageBuilder},
        futures::stream::StreamExt as _,
        std::convert::{TryFrom as _, TryInto as _},
        vfs::{directory::entry::DirectoryEntry, file::File},
    };

    const TEST_FILE_CONTENTS: [u8; 4] = [0, 1, 2, 3];

    struct TestEnv {
        _blobfs_fake: FakeBlobfs,
    }

    impl TestEnv {
        async fn new() -> (Self, MetaFile) {
            let pkg = PackageBuilder::new("pkg")
                .add_resource_at("meta/file", &TEST_FILE_CONTENTS[..])
                .build()
                .await
                .unwrap();
            let (metafar_blob, _) = pkg.contents();
            let (blobfs_fake, blobfs_client) = FakeBlobfs::new();
            blobfs_fake.add_blob(metafar_blob.merkle, metafar_blob.contents);
            let root_dir = RootDir::new(blobfs_client, metafar_blob.merkle).await.unwrap();
            let location = *root_dir.meta_files.get("meta/file").unwrap();
            (TestEnv { _blobfs_fake: blobfs_fake }, MetaFile::new(Arc::new(root_dir), location))
        }
    }

    fn node_to_file_proxy(proxy: fio::NodeProxy) -> fio::FileProxy {
        fio::FileProxy::from_channel(proxy.into_channel().unwrap())
    }

    #[fuchsia_async::run_singlethreaded(test)]
    async fn vmo() {
        let (_env, meta_file) = TestEnv::new().await;

        // VMO is readable
        let vmo = meta_file.vmo().await.unwrap();
        let mut buf = [0u8; 8];
        vmo.read(&mut buf, 0).unwrap();
        assert_eq!(buf, [0, 1, 2, 3, 0, 0, 0, 0]);
        assert_eq!(
            vmo.get_content_size().unwrap(),
            u64::try_from(TEST_FILE_CONTENTS.len()).unwrap()
        );

        // VMO not writable
        assert_eq!(vmo.write(&[0], 0), Err(zx::Status::ACCESS_DENIED));

        // Accessing the VMO caches it
        assert!(meta_file.vmo.get().is_some());

        // Accessing the VMO through the cached path works
        let vmo = meta_file.vmo().await.unwrap();
        let mut buf = [0u8; 8];
        vmo.read(&mut buf, 0).unwrap();
        assert_eq!(buf, [0, 1, 2, 3, 0, 0, 0, 0]);
        assert_eq!(vmo.write(&[0], 0), Err(zx::Status::ACCESS_DENIED));
        assert_eq!(
            vmo.get_content_size().unwrap(),
            u64::try_from(TEST_FILE_CONTENTS.len()).unwrap()
        );
    }

    #[fuchsia_async::run_singlethreaded(test)]
    async fn directory_entry_open_rejects_non_empty_path() {
        let (_env, meta_file) = TestEnv::new().await;
        let (proxy, server_end) = fidl::endpoints::create_proxy().unwrap();

        DirectoryEntry::open(
            Arc::new(meta_file),
            ExecutionScope::new(),
            fio::OpenFlags::DESCRIBE,
            0,
            VfsPath::validate_and_split("non-empty").unwrap(),
            server_end,
        );

        assert_matches!(
            node_to_file_proxy(proxy).take_event_stream().next().await,
            Some(Ok(fio::FileEvent::OnOpen_{ s, info: None}))
                if s == zx::Status::NOT_DIR.into_raw()
        );
    }

    #[fuchsia_async::run_singlethreaded(test)]
    async fn directory_entry_open_rejects_disallowed_flags() {
        let (_env, meta_file) = TestEnv::new().await;
        let meta_file = Arc::new(meta_file);

        for forbidden_flag in [
            fio::OpenFlags::RIGHT_WRITABLE,
            fio::OpenFlags::RIGHT_EXECUTABLE,
            fio::OpenFlags::CREATE,
            fio::OpenFlags::CREATE_IF_ABSENT,
            fio::OpenFlags::TRUNCATE,
            fio::OpenFlags::APPEND,
        ] {
            let (proxy, server_end) = fidl::endpoints::create_proxy().unwrap();
            DirectoryEntry::open(
                Arc::clone(&meta_file),
                ExecutionScope::new(),
                fio::OpenFlags::DESCRIBE | forbidden_flag,
                0,
                VfsPath::dot(),
                server_end,
            );

            assert_matches!(
                node_to_file_proxy(proxy).take_event_stream().next().await,
                Some(Ok(fio::FileEvent::OnOpen_{ s, info: None}))
                    if s == zx::Status::NOT_SUPPORTED.into_raw()
            );
        }
    }

    #[fuchsia_async::run_singlethreaded(test)]
    async fn directory_entry_open_succeeds() {
        let (_env, meta_file) = TestEnv::new().await;
        let (proxy, server_end) = fidl::endpoints::create_proxy().unwrap();

        DirectoryEntry::open(
            Arc::new(meta_file),
            ExecutionScope::new(),
            fio::OpenFlags::DESCRIBE,
            0,
            VfsPath::dot(),
            server_end,
        );

        assert_matches!(
            node_to_file_proxy(proxy).take_event_stream().next().await,
            Some(Ok(fio::FileEvent::OnOpen_ { s, info: Some(_) }))
                if s == zx::Status::OK.into_raw()
        );
    }

    #[fuchsia_async::run_singlethreaded(test)]
    async fn directory_entry_entry_info() {
        let (_env, meta_file) = TestEnv::new().await;

        assert_eq!(
            DirectoryEntry::entry_info(&meta_file),
            EntryInfo::new(fio::INO_UNKNOWN, fio::DirentType::File)
        );
    }

    #[fuchsia_async::run_singlethreaded(test)]
    async fn file_open() {
        let (_env, meta_file) = TestEnv::new().await;

        assert_eq!(File::open(&meta_file, fio::OpenFlags::empty()).await, Ok(()));
    }

    #[fuchsia_async::run_singlethreaded(test)]
    async fn file_read_at_adjusts_offset() {
        let (_env, meta_file) = TestEnv::new().await;
        let mut buffer = [0u8];

        for (i, e) in TEST_FILE_CONTENTS.iter().enumerate() {
            assert_eq!(File::read_at(&meta_file, i.try_into().unwrap(), &mut buffer).await, Ok(1));
            assert_eq!(&buffer, &[*e]);
        }
    }

    #[fuchsia_async::run_singlethreaded(test)]
    async fn file_read_at_past_end_returns_no_bytes() {
        let (_env, meta_file) = TestEnv::new().await;
        let mut buffer = [0u8];

        for i in 0..=1 {
            assert_eq!(
                File::read_at(
                    &meta_file,
                    u64::try_from(TEST_FILE_CONTENTS.len()).unwrap() + i,
                    &mut buffer
                )
                .await,
                Ok(0)
            );
            assert_eq!(&buffer, &[0]);
        }
    }

    #[fuchsia_async::run_singlethreaded(test)]
    async fn file_read_at_caps_count() {
        let (_env, meta_file) = TestEnv::new().await;
        let mut buffer = [0u8; 5];

        assert_eq!(File::read_at(&meta_file, 2, &mut buffer).await, Ok(2));
        assert_eq!(&buffer, &[2, 3, 0, 0, 0]);
    }

    #[fuchsia_async::run_singlethreaded(test)]
    async fn file_write_at() {
        let (_env, meta_file) = TestEnv::new().await;

        assert_eq!(File::write_at(&meta_file, 0, &[]).await, Err(zx::Status::NOT_SUPPORTED));
    }

    #[fuchsia_async::run_singlethreaded(test)]
    async fn file_append() {
        let (_env, meta_file) = TestEnv::new().await;

        assert_eq!(File::append(&meta_file, &[]).await, Err(zx::Status::NOT_SUPPORTED));
    }

    #[fuchsia_async::run_singlethreaded(test)]
    async fn file_truncate() {
        let (_env, meta_file) = TestEnv::new().await;

        assert_eq!(File::truncate(&meta_file, 0).await, Err(zx::Status::NOT_SUPPORTED));
    }

    #[fuchsia_async::run_singlethreaded(test)]
    async fn file_get_buffer_rejects_unsupported_flags() {
        let (_env, meta_file) = TestEnv::new().await;

        for flag in [fio::VmoFlags::WRITE, fio::VmoFlags::EXECUTE, fio::VmoFlags::SHARED_BUFFER] {
            assert_eq!(File::get_buffer(&meta_file, flag).await, Err(zx::Status::NOT_SUPPORTED));
        }
    }

    #[fuchsia_async::run_singlethreaded(test)]
    async fn file_get_buffer_private() {
        let (_env, meta_file) = TestEnv::new().await;

        let fidl_fuchsia_mem::Buffer { vmo, size } =
            File::get_buffer(&meta_file, fio::VmoFlags::PRIVATE_CLONE)
                .await
                .expect("get_buffer should succeed");

        assert_eq!(size, u64::try_from(TEST_FILE_CONTENTS.len()).unwrap());
        // VMO is readable
        let mut buf = [0u8; 8];
        vmo.read(&mut buf, 0).unwrap();
        assert_eq!(buf, [0, 1, 2, 3, 0, 0, 0, 0]);
        assert_eq!(
            vmo.get_content_size().unwrap(),
            u64::try_from(TEST_FILE_CONTENTS.len()).unwrap()
        );

        // VMO not writable
        assert_eq!(vmo.write(&[0], 0), Err(zx::Status::ACCESS_DENIED));

        // VMO is not shared
        assert_eq!(vmo.count_info().unwrap().handle_count, 1);
    }

    #[fuchsia_async::run_singlethreaded(test)]
    async fn file_get_buffer_not_private() {
        let (_env, meta_file) = TestEnv::new().await;

        let fidl_fuchsia_mem::Buffer { vmo, size } =
            File::get_buffer(&meta_file, fio::VmoFlags::READ)
                .await
                .expect("get_buffer should succeed");

        assert_eq!(size, u64::try_from(TEST_FILE_CONTENTS.len()).unwrap());
        // VMO is readable
        let mut buf = [0u8; 8];
        vmo.read(&mut buf, 0).unwrap();
        assert_eq!(buf, [0, 1, 2, 3, 0, 0, 0, 0]);
        assert_eq!(
            vmo.get_content_size().unwrap(),
            u64::try_from(TEST_FILE_CONTENTS.len()).unwrap()
        );

        // VMO not writable
        assert_eq!(vmo.write(&[0], 0), Err(zx::Status::ACCESS_DENIED));

        // VMO is shared
        assert_eq!(vmo.count_info().unwrap().handle_count, 2);
    }

    #[fuchsia_async::run_singlethreaded(test)]
    async fn file_get_size() {
        let (_env, meta_file) = TestEnv::new().await;

        assert_eq!(
            File::get_size(&meta_file).await,
            Ok(u64::try_from(TEST_FILE_CONTENTS.len()).unwrap())
        );
    }

    #[fuchsia_async::run_singlethreaded(test)]
    async fn file_get_attrs() {
        let (_env, meta_file) = TestEnv::new().await;

        assert_eq!(
            File::get_attrs(&meta_file).await,
            Ok(fio::NodeAttributes {
                mode: fio::MODE_TYPE_FILE | 0o400,
                id: 1,
                content_size: meta_file.location.length,
                storage_size: meta_file.location.length,
                link_count: 1,
                creation_time: 0,
                modification_time: 0,
            })
        );
    }

    #[fuchsia_async::run_singlethreaded(test)]
    async fn file_set_attrs() {
        let (_env, meta_file) = TestEnv::new().await;

        assert_eq!(
            File::set_attrs(
                &meta_file,
                fio::NodeAttributeFlags::empty(),
                fio::NodeAttributes {
                    mode: 0,
                    id: 0,
                    content_size: 0,
                    storage_size: 0,
                    link_count: 0,
                    creation_time: 0,
                    modification_time: 0,
                },
            )
            .await,
            Err(zx::Status::NOT_SUPPORTED)
        );
    }

    #[fuchsia_async::run_singlethreaded(test)]
    async fn file_close() {
        let (_env, meta_file) = TestEnv::new().await;

        assert_eq!(File::close(&meta_file).await, Ok(()));
    }

    #[fuchsia_async::run_singlethreaded(test)]
    async fn file_sync() {
        let (_env, meta_file) = TestEnv::new().await;

        assert_eq!(File::sync(&meta_file).await, Err(zx::Status::NOT_SUPPORTED));
    }
}
