// 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::{
        component_model::{BuildAnalyzerModelError, Child},
        environment::EnvironmentForAnalyzer,
        node_path::NodePath,
        route::RouteMapper,
    },
    async_trait::async_trait,
    cm_moniker::{InstancedAbsoluteMoniker, InstancedChildMoniker},
    cm_rust::{CapabilityDecl, CollectionDecl, ComponentDecl, ExposeDecl, OfferDecl, UseDecl},
    moniker::{AbsoluteMoniker, AbsoluteMonikerBase, ChildMoniker, ChildMonikerBase},
    routing::{
        capability_source::{BuiltinCapabilities, NamespaceCapabilities},
        component_id_index::ComponentIdIndex,
        component_instance::{
            ComponentInstanceInterface, ExtendedInstanceInterface, ResolvedInstanceInterface,
            TopInstanceInterface, WeakExtendedInstanceInterface,
        },
        config::RuntimeConfig,
        environment::{EnvironmentInterface, RunnerRegistry},
        error::ComponentInstanceError,
        policy::GlobalPolicyChecker,
        resolving::{ComponentAddress, ComponentResolutionContext},
    },
    std::{
        collections::HashMap,
        sync::{Arc, RwLock},
    },
};

/// A representation of a v2 component instance.
#[derive(Debug)]
pub struct ComponentInstanceForAnalyzer {
    instanced_moniker: InstancedAbsoluteMoniker,
    abs_moniker: AbsoluteMoniker,
    pub(crate) decl: ComponentDecl,
    url: String,
    parent: WeakExtendedInstanceInterface<Self>,
    children: RwLock<HashMap<ChildMoniker, Arc<Self>>>,
    pub(crate) environment: Arc<EnvironmentForAnalyzer>,
    policy_checker: GlobalPolicyChecker,
    component_id_index: Arc<ComponentIdIndex>,
    persistent_storage: bool,
}

impl ComponentInstanceForAnalyzer {
    /// Exposes the component's ComponentDecl. This is referenced directly in tests.
    pub fn decl_for_testing(&self) -> &ComponentDecl {
        &self.decl
    }

    /// Returns a representation of the instance's position in the component instance tree.
    pub fn node_path(&self) -> NodePath {
        NodePath::absolute_from_vec(
            self.abs_moniker.path().into_iter().map(|m| m.as_str()).collect(),
        )
    }

    // Creates a new root component instance.
    pub(crate) fn new_root(
        decl: ComponentDecl,
        url: String,
        top_instance: Arc<TopInstanceForAnalyzer>,
        runtime_config: Arc<RuntimeConfig>,
        policy_checker: GlobalPolicyChecker,
        component_id_index: Arc<ComponentIdIndex>,
        runner_registry: RunnerRegistry,
        persistent_storage: bool,
    ) -> Arc<Self> {
        let environment =
            EnvironmentForAnalyzer::new_root(runner_registry, &runtime_config, &top_instance);
        let instanced_moniker = InstancedAbsoluteMoniker::root();
        let abs_moniker = instanced_moniker.clone().without_instance_ids();
        Arc::new(Self {
            instanced_moniker,
            abs_moniker,
            decl,
            url,
            parent: WeakExtendedInstanceInterface::from(&ExtendedInstanceInterface::AboveRoot(
                top_instance,
            )),
            children: RwLock::new(HashMap::new()),
            environment,
            policy_checker,
            component_id_index,
            persistent_storage,
        })
    }

    // Creates a new non-root component instance as a child of `parent`.
    pub(crate) fn new_for_child(
        child: &Child,
        absolute_url: String,
        child_component_decl: ComponentDecl,
        parent: Arc<Self>,
        policy_checker: GlobalPolicyChecker,
        component_id_index: Arc<ComponentIdIndex>,
    ) -> Result<Arc<Self>, BuildAnalyzerModelError> {
        let environment = EnvironmentForAnalyzer::new_for_child(&parent, child)?;
        let instanced_moniker = parent.instanced_moniker.child(InstancedChildMoniker::new(
            child.child_moniker.name.clone(),
            child.child_moniker.collection.clone(),
            0,
        ));
        let abs_moniker = instanced_moniker.clone().without_instance_ids();
        let persistent_storage = parent.persistent_storage();
        Ok(Arc::new(Self {
            instanced_moniker,
            abs_moniker,
            decl: child_component_decl,
            url: absolute_url,
            parent: WeakExtendedInstanceInterface::from(&ExtendedInstanceInterface::Component(
                parent,
            )),
            children: RwLock::new(HashMap::new()),
            environment,
            policy_checker,
            component_id_index,
            persistent_storage,
        }))
    }

    // Returns all children of the component instance.
    pub(crate) fn get_children(&self) -> Vec<Arc<Self>> {
        self.children
            .read()
            .expect("failed to acquire read lock")
            .values()
            .map(|c| Arc::clone(c))
            .collect()
    }

    // Adds a new child to this component instance.
    pub(crate) fn add_child(&self, child_moniker: ChildMoniker, child: Arc<Self>) {
        self.children.write().expect("failed to acquire write lock").insert(child_moniker, child);
    }

    // A (nearly) no-op sync function used to implement the async trait method `lock_resolved_instance`
    // for `ComponentInstanceInterface`.
    pub(crate) fn resolve<'a>(
        self: &'a Arc<Self>,
    ) -> Result<Box<dyn ResolvedInstanceInterface<Component = Self> + 'a>, ComponentInstanceError>
    {
        Ok(Box::new(&**self))
    }

    pub fn environment(&self) -> &Arc<EnvironmentForAnalyzer> {
        &self.environment
    }
}

#[async_trait]
impl ComponentInstanceInterface for ComponentInstanceForAnalyzer {
    type TopInstance = TopInstanceForAnalyzer;
    type DebugRouteMapper = RouteMapper;

    fn instanced_moniker(&self) -> &InstancedAbsoluteMoniker {
        &self.instanced_moniker
    }

    fn abs_moniker(&self) -> &AbsoluteMoniker {
        &self.abs_moniker
    }

    fn child_moniker(&self) -> Option<&ChildMoniker> {
        self.abs_moniker.leaf()
    }

    fn instanced_child_moniker(&self) -> Option<&InstancedChildMoniker> {
        self.instanced_moniker.leaf()
    }

    fn url(&self) -> &str {
        &self.url
    }

    fn environment(&self) -> &dyn EnvironmentInterface<Self> {
        self.environment.as_ref()
    }

    fn try_get_parent(&self) -> Result<ExtendedInstanceInterface<Self>, ComponentInstanceError> {
        Ok(self.parent.upgrade()?)
    }

    fn try_get_policy_checker(&self) -> Result<GlobalPolicyChecker, ComponentInstanceError> {
        Ok(self.policy_checker.clone())
    }

    fn try_get_component_id_index(&self) -> Result<Arc<ComponentIdIndex>, ComponentInstanceError> {
        Ok(Arc::clone(&self.component_id_index))
    }

    // The trait definition requires this function to be async, but `ComponentInstanceForAnalyzer`'s
    // implementation must not await. This method is called by `route_capability`, which must
    // return immediately for `ComponentInstanceForAnalyzer` (see
    // `ComponentModelForAnalyzer::route_capability_sync()`).
    //
    // TODO(fxbug.dev/87204): Remove this comment when Scrutiny's `DataController` can make async
    // function calls.
    async fn lock_resolved_state<'a>(
        self: &'a Arc<Self>,
    ) -> Result<
        Box<dyn ResolvedInstanceInterface<Component = ComponentInstanceForAnalyzer> + 'a>,
        ComponentInstanceError,
    > {
        self.resolve()
    }

    fn new_route_mapper() -> RouteMapper {
        RouteMapper::new()
    }

    fn persistent_storage(&self) -> bool {
        self.persistent_storage
    }
}

impl ResolvedInstanceInterface for ComponentInstanceForAnalyzer {
    type Component = Self;

    fn uses(&self) -> Vec<UseDecl> {
        self.decl.uses.clone()
    }

    fn exposes(&self) -> Vec<ExposeDecl> {
        self.decl.exposes.clone()
    }

    fn offers(&self) -> Vec<OfferDecl> {
        self.decl.offers.clone()
    }

    fn capabilities(&self) -> Vec<CapabilityDecl> {
        self.decl.capabilities.clone()
    }

    fn collections(&self) -> Vec<CollectionDecl> {
        self.decl.collections.clone()
    }

    fn get_child(&self, moniker: &ChildMoniker) -> Option<Arc<Self>> {
        self.children.read().expect("failed to acquire read lock").get(moniker).map(Arc::clone)
    }

    // This is a static model with no notion of a collection.
    fn children_in_collection(&self, _collection: &str) -> Vec<(ChildMoniker, Arc<Self>)> {
        vec![]
    }

    fn address(&self) -> ComponentAddress {
        ComponentAddress::new_absolute("", "", "", None, None)
    }

    fn context_to_resolve_children(&self) -> Option<ComponentResolutionContext> {
        None
    }
}

/// A representation of `ComponentManager`'s instance, providing a set of capabilities to
/// the root component instance.
#[derive(Debug, Default)]
pub struct TopInstanceForAnalyzer {
    namespace_capabilities: NamespaceCapabilities,
    builtin_capabilities: BuiltinCapabilities,
}

impl TopInstanceForAnalyzer {
    pub fn new(
        namespace_capabilities: NamespaceCapabilities,
        builtin_capabilities: BuiltinCapabilities,
    ) -> Arc<Self> {
        Arc::new(Self { namespace_capabilities, builtin_capabilities })
    }
}

impl TopInstanceInterface for TopInstanceForAnalyzer {
    fn namespace_capabilities(&self) -> &NamespaceCapabilities {
        &self.namespace_capabilities
    }

    fn builtin_capabilities(&self) -> &BuiltinCapabilities {
        &self.builtin_capabilities
    }
}

#[cfg(test)]
mod tests {
    use {super::*, cm_rust_testing::ComponentDeclBuilder, futures::FutureExt};

    // Spot-checks that `ComponentInstanceForAnalyzer`'s implementation of the `ComponentInstanceInterface`
    // trait method `lock_resolved_state()` returns immediately. In addition, updates to that method should
    // be reviewed to make sure that this property holds; otherwise, `ComponentModelForAnalyzer`'s sync
    // methods may panic.
    #[test]
    fn lock_resolved_state_is_sync() {
        let decl = ComponentDeclBuilder::new().build();
        let url = "some_url".to_string();

        let instance = ComponentInstanceForAnalyzer::new_root(
            decl,
            url,
            TopInstanceForAnalyzer::new(vec![], vec![]),
            Arc::new(RuntimeConfig::default()),
            GlobalPolicyChecker::default(),
            Arc::new(ComponentIdIndex::default()),
            RunnerRegistry::default(),
            false,
        );

        assert!(instance.lock_resolved_state().now_or_never().is_some())
    }
}
