// Copyright 2019 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::model::{
        component::{ComponentInstance, WeakComponentInstance},
        error::ModelError,
        routing::{route_and_open_capability, OpenOptions, OpenResolverOptions, RouteRequest},
    },
    ::routing::component_instance::ComponentInstanceInterface,
    anyhow::Error,
    async_trait::async_trait,
    clonable_error::ClonableError,
    cm_rust::ResolverRegistration,
    fidl_fuchsia_io as fio, fidl_fuchsia_mem as fmem, fidl_fuchsia_sys2 as fsys,
    fuchsia_zircon::Status,
    std::{collections::HashMap, sync::Arc},
    thiserror::Error,
    url::Url,
};

/// Resolves a component URL to its content.
/// TODO: Consider defining an internal representation for `fsys::Component` so as to
/// further isolate the `Model` from FIDL interfacting concerns.
#[async_trait]
pub trait Resolver {
    async fn resolve(&self, component_url: &str) -> Result<ResolvedComponent, ResolverError>;
}

/// The response returned from a Resolver. This struct is derived from the FIDL
/// [`fuchsia.sys2.Component`][fidl_fuchsia_sys2::Component] table, except that
/// the opaque binary ComponentDecl has been deserialized and validated.
#[derive(Debug)]
pub struct ResolvedComponent {
    pub resolved_url: String,
    pub decl: fsys::ComponentDecl,
    pub package: Option<fsys::Package>,
}

/// Resolves a component URL using a resolver selected based on the URL's scheme.
#[derive(Default)]
pub struct ResolverRegistry {
    resolvers: HashMap<String, Box<dyn Resolver + Send + Sync + 'static>>,
}

impl ResolverRegistry {
    pub fn new() -> ResolverRegistry {
        Default::default()
    }

    pub fn register(
        &mut self,
        scheme: String,
        resolver: Box<dyn Resolver + Send + Sync + 'static>,
    ) {
        // ComponentDecl validation checks that there aren't any duplicate schemes.
        assert!(
            self.resolvers.insert(scheme, resolver).is_none(),
            "Found duplicate scheme in ComponentDecl"
        );
    }

    /// Creates and populates a `ResolverRegistry` with `RemoteResolvers` that
    /// have been registered with an environment.
    pub fn from_decl(decl: &[ResolverRegistration], parent: &Arc<ComponentInstance>) -> Self {
        let mut registry = ResolverRegistry::new();
        for resolver in decl {
            registry.register(
                resolver.scheme.clone().into(),
                Box::new(RemoteResolver::new(resolver.clone(), parent.as_weak())),
            );
        }
        registry
    }
}

#[async_trait]
impl Resolver for ResolverRegistry {
    async fn resolve(&self, component_url: &str) -> Result<ResolvedComponent, ResolverError> {
        match Url::parse(component_url) {
            Ok(parsed_url) => {
                if let Some(ref resolver) = self.resolvers.get(parsed_url.scheme()) {
                    resolver.resolve(component_url).await
                } else {
                    Err(ResolverError::SchemeNotRegistered)
                }
            }
            Err(e) => Err(ResolverError::malformed_url(e)),
        }
    }
}

/// A resolver whose implementation lives in an external component. The source
/// of the resolver is determined through capability routing.
pub struct RemoteResolver {
    registration: ResolverRegistration,
    component: WeakComponentInstance,
}

impl RemoteResolver {
    pub fn new(registration: ResolverRegistration, component: WeakComponentInstance) -> Self {
        RemoteResolver { registration, component }
    }
}

// TODO(61288): Implement some sort of caching of the routed capability. Multiple
// component URL resolutions should be possible on a single channel.
#[async_trait]
impl Resolver for RemoteResolver {
    async fn resolve(&self, component_url: &str) -> Result<ResolvedComponent, ResolverError> {
        let (proxy, server_end) = fidl::endpoints::create_proxy::<fsys::ComponentResolverMarker>()
            .map_err(ResolverError::internal)?;
        let component = self.component.upgrade().map_err(ResolverError::routing_error)?;
        let open_options = OpenResolverOptions {
            flags: fio::OPEN_RIGHT_READABLE | fio::OPEN_RIGHT_WRITABLE,
            open_mode: fio::MODE_TYPE_SERVICE,
            server_chan: &mut server_end.into_channel(),
        };
        route_and_open_capability(
            RouteRequest::Resolver(self.registration.clone()),
            &component,
            OpenOptions::Resolver(open_options),
        )
        .await
        .map_err(ResolverError::routing_error)?;
        let component = proxy.resolve(component_url).await.map_err(ResolverError::fidl_error)??;
        let decl_buffer: fmem::Data = component.decl.ok_or(ResolverError::RemoteInvalidData)?;
        Ok(ResolvedComponent {
            resolved_url: component.resolved_url.ok_or(ResolverError::RemoteInvalidData)?,
            decl: read_and_validate_manifest(decl_buffer).await?,
            package: component.package,
        })
    }
}

async fn read_and_validate_manifest(
    data: fmem::Data,
) -> Result<fsys::ComponentDecl, ResolverError> {
    let bytes = match data {
        fmem::Data::Bytes(bytes) => bytes,
        fmem::Data::Buffer(buffer) => {
            let mut contents = Vec::<u8>::new();
            contents.resize(buffer.size as usize, 0);
            buffer.vmo.read(&mut contents, 0).map_err(ResolverError::ManifestIo)?;
            contents
        }
        _ => return Err(ResolverError::RemoteInvalidData),
    };
    let component_decl: fsys::ComponentDecl = fidl::encoding::decode_persistent(&bytes)
        .map_err(|err| ResolverError::manifest_invalid(err))?;
    cm_fidl_validator::validate(&component_decl).map_err(|e| ResolverError::manifest_invalid(e))?;
    Ok(component_decl)
}

/// Errors produced by `Resolver`.
#[derive(Debug, Error, Clone)]
pub enum ResolverError {
    #[error("an unexpected error occurred: {0}")]
    Internal(#[source] ClonableError),
    #[error("an IO error occurred: {0}")]
    Io(#[source] ClonableError),
    #[error("component manifest not found: {0}")]
    ManifestNotFound(#[source] ClonableError),
    #[error("package not found: {0}")]
    PackageNotFound(#[source] ClonableError),
    #[error("component manifest invalid: {0}")]
    ManifestInvalid(#[source] ClonableError),
    #[error("failed to read manifest: {0}")]
    ManifestIo(Status),
    #[error("Model not available")]
    ModelNotAvailable,
    #[error("scheme not registered")]
    SchemeNotRegistered,
    #[error("malformed url: {0}")]
    MalformedUrl(#[source] ClonableError),
    #[error("url missing resource")]
    UrlMissingResource,
    #[error("failed to route resolver capability: {0}")]
    RoutingError(#[source] Box<ModelError>),
    #[error("the remote resolver returned invalid data")]
    RemoteInvalidData,
    #[error("an error occurred sending a FIDL request to the remote resolver: {0}")]
    FidlError(#[source] ClonableError),
}

impl ResolverError {
    pub fn internal(err: impl Into<Error>) -> ResolverError {
        ResolverError::Internal(err.into().into())
    }

    pub fn io(err: impl Into<Error>) -> ResolverError {
        ResolverError::Io(err.into().into())
    }

    pub fn manifest_not_found(err: impl Into<Error>) -> ResolverError {
        ResolverError::ManifestNotFound(err.into().into())
    }

    pub fn package_not_found(err: impl Into<Error>) -> ResolverError {
        ResolverError::PackageNotFound(err.into().into())
    }

    pub fn manifest_invalid(err: impl Into<Error>) -> ResolverError {
        ResolverError::ManifestInvalid(err.into().into())
    }

    pub fn malformed_url(err: impl Into<Error>) -> ResolverError {
        ResolverError::MalformedUrl(err.into().into())
    }

    pub fn routing_error(err: impl Into<ModelError>) -> ResolverError {
        ResolverError::RoutingError(Box::new(err.into()))
    }

    pub fn fidl_error(err: impl Into<Error>) -> ResolverError {
        ResolverError::FidlError(err.into().into())
    }
}

impl From<fsys::ResolverError> for ResolverError {
    fn from(err: fsys::ResolverError) -> ResolverError {
        match err {
            fsys::ResolverError::Internal => ResolverError::internal(RemoteError(err)),
            fsys::ResolverError::Io => ResolverError::io(RemoteError(err)),
            fsys::ResolverError::PackageNotFound
            | fsys::ResolverError::NoSpace
            | fsys::ResolverError::ResourceUnavailable
            | fsys::ResolverError::NotSupported => {
                ResolverError::package_not_found(RemoteError(err))
            }
            fsys::ResolverError::ManifestNotFound => {
                ResolverError::manifest_not_found(RemoteError(err))
            }
            fsys::ResolverError::InvalidArgs => ResolverError::malformed_url(RemoteError(err)),
        }
    }
}

#[derive(Error, Clone, Debug)]
#[error("remote resolver responded with {0:?}")]
struct RemoteError(fsys::ResolverError);

#[cfg(test)]
mod tests {
    use {super::*, anyhow::format_err};

    struct MockOkResolver {
        pub expected_url: String,
        pub resolved_url: String,
    }

    #[async_trait]
    impl Resolver for MockOkResolver {
        async fn resolve(&self, component_url: &str) -> Result<ResolvedComponent, ResolverError> {
            assert_eq!(self.expected_url, component_url);
            Ok(ResolvedComponent {
                resolved_url: self.resolved_url.clone(),
                decl: fsys::ComponentDecl {
                    program: None,
                    uses: None,
                    exposes: None,
                    offers: None,
                    facets: None,
                    capabilities: None,
                    children: None,
                    collections: None,
                    environments: None,
                    ..fsys::ComponentDecl::EMPTY
                },
                package: None,
            })
        }
    }

    struct MockErrorResolver {
        pub expected_url: String,
        pub error: Box<dyn Fn(&str) -> ResolverError + Send + Sync + 'static>,
    }

    #[async_trait]
    impl Resolver for MockErrorResolver {
        async fn resolve(&self, component_url: &str) -> Result<ResolvedComponent, ResolverError> {
            assert_eq!(self.expected_url, component_url);
            Err((self.error)(component_url))
        }
    }

    #[fuchsia_async::run_until_stalled(test)]
    async fn register_and_resolve() {
        let mut registry = ResolverRegistry::new();
        registry.register(
            "foo".to_string(),
            Box::new(MockOkResolver {
                expected_url: "foo://url".to_string(),
                resolved_url: "foo://resolved".to_string(),
            }),
        );
        registry.register(
            "bar".to_string(),
            Box::new(MockErrorResolver {
                expected_url: "bar://url".to_string(),
                error: Box::new(|_| {
                    ResolverError::manifest_not_found(format_err!("not available"))
                }),
            }),
        );

        // Resolve known scheme that returns success.
        let component = registry.resolve("foo://url").await.unwrap();
        assert_eq!("foo://resolved", component.resolved_url);

        // Resolve a different scheme that produces an error.
        let expected_res: Result<ResolvedComponent, ResolverError> =
            Err(ResolverError::manifest_not_found(format_err!("not available")));
        assert_eq!(
            format!("{:?}", expected_res),
            format!("{:?}", registry.resolve("bar://url").await)
        );

        // Resolve an unknown scheme
        let expected_res: Result<ResolvedComponent, ResolverError> =
            Err(ResolverError::SchemeNotRegistered);
        assert_eq!(
            format!("{:?}", expected_res),
            format!("{:?}", registry.resolve("unknown://url").await),
        );

        // Resolve an URL lacking a scheme.
        let expected_res: Result<ResolvedComponent, ResolverError> =
            Err(ResolverError::malformed_url(url::ParseError::RelativeUrlWithoutBase));
        assert_eq!(format!("{:?}", expected_res), format!("{:?}", registry.resolve("xxx").await),);
    }

    #[test]
    #[should_panic(expected = "Found duplicate scheme in ComponentDecl")]
    fn test_duplicate_registration() {
        let mut registry = ResolverRegistry::new();
        let resolver_a =
            MockOkResolver { expected_url: "".to_string(), resolved_url: "".to_string() };
        let resolver_b =
            MockOkResolver { expected_url: "".to_string(), resolved_url: "".to_string() };
        registry.register("fuchsia-pkg".to_string(), Box::new(resolver_a));
        registry.register("fuchsia-pkg".to_string(), Box::new(resolver_b));
    }

    #[test]
    fn test_multiple_scheme_registration() {
        let mut registry = ResolverRegistry::new();
        let resolver_a =
            MockOkResolver { expected_url: "".to_string(), resolved_url: "".to_string() };
        let resolver_b =
            MockOkResolver { expected_url: "".to_string(), resolved_url: "".to_string() };
        registry.register("fuchsia-pkg".to_string(), Box::new(resolver_a));
        registry.register("fuchsia-boot".to_string(), Box::new(resolver_b));
    }
}
