// Copyright 2020 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 {
    super::collection::AssetCollectionError,
    anyhow::{format_err, Error},
    async_trait::async_trait,
    fidl::endpoints::create_proxy,
    fidl_fuchsia_io as io, fidl_fuchsia_mem as mem,
    fidl_fuchsia_pkg::{FontResolverMarker, UpdatePolicy},
    fuchsia_component::client::connect_to_service,
    fuchsia_trace as trace, fuchsia_zircon as zx,
    manifest::v2,
    std::{fs::File, path::Path},
};

/// A trait that covers the interactions of the font service with `fuchsia.pkg.FontResolver` and
/// font asset VMOs. Intended for easier testing.
#[async_trait]
pub trait AssetLoader {
    /// Resolves a font package to its `Directory`.
    async fn fetch_package_directory(
        &self,
        package_locator: &v2::PackageLocator,
    ) -> Result<io::DirectoryProxy, AssetCollectionError>;

    /// Gets a `VMO` handle to the [`Asset`] at a local `path`.
    fn load_vmo_from_path(&self, path: &Path) -> Result<mem::Buffer, AssetCollectionError>;

    /// Gets a VMO handle to the file with the given `file_name` within the given directory.
    /// The `package_locator` is used for detailed error messages.
    async fn load_vmo_from_directory_proxy(
        &self,
        directory_proxy: io::DirectoryProxy,
        package_locator: &v2::PackageLocator,
        file_name: &str,
    ) -> Result<mem::Buffer, AssetCollectionError>;
}

/// Real implementation of [`AssetLoader`].
pub struct AssetLoaderImpl {}

impl AssetLoaderImpl {
    /// Creates a new instance of `AssetLoaderImpl`.
    pub fn new() -> Self {
        AssetLoaderImpl {}
    }
}

/// This implementation is currently covered by integration tests only.
/// TODO(fxbug.dev/48649): Unit tests.
#[async_trait]
impl AssetLoader for AssetLoaderImpl {
    async fn fetch_package_directory(
        &self,
        package_locator: &v2::PackageLocator,
    ) -> Result<io::DirectoryProxy, AssetCollectionError> {
        let package_url = package_locator.url.to_string();
        trace::duration!(
            "fonts",
            "asset:fetcher:fetch_package_directory",
            "package_url" => &package_url[..]);

        // Get directory handle from FontResolver
        let font_resolver = connect_to_service::<FontResolverMarker>()
            .map_err(|e| AssetCollectionError::ServiceConnectionError(e.into()))?;
        let mut update_policy = UpdatePolicy { fetch_if_absent: true, allow_old_versions: false };
        let (dir_proxy, dir_request) = create_proxy::<io::DirectoryMarker>()
            .map_err(|e| AssetCollectionError::ServiceConnectionError(e.into()))?;

        let response =
            font_resolver.resolve(&package_url, &mut update_policy, dir_request).await.map_err(
                |e| AssetCollectionError::PackageResolverError(package_locator.clone(), e.into()),
            )?;
        let () = response.map_err(|i| {
            AssetCollectionError::PackageResolverError(
                package_locator.clone(),
                zx::Status::from_raw(i).into(),
            )
        })?;

        Ok(dir_proxy)
    }

    fn load_vmo_from_path(&self, path: &Path) -> Result<mem::Buffer, AssetCollectionError> {
        let path_string = path.to_str().unwrap_or_default();
        trace::duration!(
                "fonts",
                "asset:fetcher:load_vmo_from_path",
                "path" => path_string);
        let file = File::open(path)
            .map_err(|e| AssetCollectionError::LocalFileNotAccessible(path.to_owned(), e.into()))?;
        let vmo = fdio::get_vmo_copy_from_file(&file)
            .map_err(|e| AssetCollectionError::LocalFileNotAccessible(path.to_owned(), e.into()))?;
        let size = file
            .metadata()
            .map_err(|e| AssetCollectionError::LocalFileNotAccessible(path.to_owned(), e.into()))?
            .len();
        Ok(mem::Buffer { vmo, size })
    }

    async fn load_vmo_from_directory_proxy(
        &self,
        directory_proxy: io::DirectoryProxy,
        package_locator: &v2::PackageLocator,
        file_name: &str,
    ) -> Result<mem::Buffer, AssetCollectionError> {
        trace::duration!(
            "fonts",
            "asset:collection:load_buffer_from_directory_proxy",
            "file_name" => file_name);

        let packaged_file_error = |cause: Error| AssetCollectionError::PackagedFileError {
            file_name: file_name.to_string(),
            package_locator: package_locator.clone(),
            cause,
        };

        let file_proxy =
            io_util::open_file(&directory_proxy, Path::new(&file_name), io::OPEN_RIGHT_READABLE)
                .map_err(|e| packaged_file_error(e))?;

        let (status, buffer) = file_proxy
            .get_buffer(io::VMO_FLAG_READ)
            .await
            .map_err(|e| packaged_file_error(e.into()))?;

        zx::Status::ok(status).map_err(|e| packaged_file_error(e.into()))?;

        buffer.map(|b| *b).ok_or_else(|| {
            packaged_file_error(
                format_err!(
                    "Inexplicably failed to access buffer after opening the file successfully"
                )
                .into(),
            )
        })
    }
}
