// 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 {
    crate::model::{
        component::{
            ComponentInstance, ComponentManagerInstance, ExtendedInstance, WeakExtendedInstance,
        },
        resolver::{ResolvedComponent, Resolver, ResolverError, ResolverRegistry},
    },
    ::routing::environment::EnvironmentInterface,
    async_trait::async_trait,
    cm_rust::EnvironmentDecl,
    fidl_fuchsia_sys2 as fsys,
    std::{
        sync::{Arc, Weak},
        time::Duration,
    },
};

// TODO(https://fxbug.dev/71901): remove aliases once the routing lib has a stable API.
pub type EnvironmentExtends = ::routing::environment::EnvironmentExtends;
pub type RunnerRegistry = ::routing::environment::RunnerRegistry;
pub type DebugRegistry = ::routing::environment::DebugRegistry;
pub type DebugRegistration = ::routing::environment::DebugRegistration;

/// A realm's environment, populated from a component's [`EnvironmentDecl`].
/// An environment defines intrinsic behaviors of a component's realm. Components
/// can define an environment, but do not interact with it directly.
///
/// [`EnvironmentDecl`]: fidl_fuchsia_sys2::EnvironmentDecl
pub struct Environment {
    /// Name of this environment as defined by its creator.
    /// Would be `None` for root environment.
    name: Option<String>,
    /// The parent that created or inherited the environment.
    parent: WeakExtendedInstance,
    /// The extension mode of this environment.
    extends: EnvironmentExtends,
    /// The runners available in this environment.
    runner_registry: RunnerRegistry,
    /// The resolvers in this environment, mapped to URL schemes.
    resolver_registry: ResolverRegistry,
    /// Protocols available in this environment as debug capabilities.
    debug_registry: DebugRegistry,
    /// The deadline for runners to respond to `ComponentController.Stop` calls.
    stop_timeout: Duration,
}

pub const DEFAULT_STOP_TIMEOUT: Duration = Duration::from_secs(5);

impl Environment {
    /// Creates a new empty environment parented to component manager.
    pub fn empty() -> Environment {
        Environment {
            name: None,
            parent: WeakExtendedInstance::AboveRoot(Weak::new()),
            extends: EnvironmentExtends::None,
            runner_registry: RunnerRegistry::default(),
            resolver_registry: ResolverRegistry::new(),
            debug_registry: DebugRegistry::default(),
            stop_timeout: DEFAULT_STOP_TIMEOUT,
        }
    }

    /// Creates a new root environment with a resolver registry, parented to component manager.
    pub fn new_root(
        top_instance: &Arc<ComponentManagerInstance>,
        runner_registry: RunnerRegistry,
        resolver_registry: ResolverRegistry,
        debug_registry: DebugRegistry,
    ) -> Environment {
        Environment {
            name: None,
            parent: WeakExtendedInstance::AboveRoot(Arc::downgrade(top_instance)),
            extends: EnvironmentExtends::None,
            runner_registry,
            resolver_registry,
            debug_registry,
            stop_timeout: DEFAULT_STOP_TIMEOUT,
        }
    }

    /// Creates an environment from `env_decl`, using `parent` as the parent realm.
    pub fn from_decl(parent: &Arc<ComponentInstance>, env_decl: &EnvironmentDecl) -> Environment {
        Environment {
            name: Some(env_decl.name.clone()),
            parent: WeakExtendedInstance::Component(parent.into()),
            extends: env_decl.extends.into(),
            runner_registry: RunnerRegistry::from_decl(&env_decl.runners),
            resolver_registry: ResolverRegistry::from_decl(&env_decl.resolvers, parent),
            debug_registry: env_decl.debug_capabilities.clone().into(),
            stop_timeout: match env_decl.stop_timeout_ms {
                Some(timeout) => Duration::from_millis(timeout.into()),
                None => match env_decl.extends {
                    fsys::EnvironmentExtends::Realm => parent.environment.stop_timeout(),
                    fsys::EnvironmentExtends::None => {
                        panic!("EnvironmentDecl is missing stop_timeout");
                    }
                },
            },
        }
    }

    /// Creates a new environment with `parent` as the parent.
    pub fn new_inheriting(parent: &Arc<ComponentInstance>) -> Environment {
        Environment {
            name: None,
            parent: WeakExtendedInstance::Component(parent.into()),
            extends: EnvironmentExtends::Realm,
            runner_registry: RunnerRegistry::default(),
            resolver_registry: ResolverRegistry::new(),
            debug_registry: DebugRegistry::default(),
            stop_timeout: parent.environment.stop_timeout(),
        }
    }

    pub fn stop_timeout(&self) -> Duration {
        self.stop_timeout
    }
}

impl EnvironmentInterface<ComponentInstance> for Environment {
    fn name(&self) -> Option<&str> {
        self.name.as_deref()
    }

    fn parent(&self) -> &WeakExtendedInstance {
        &self.parent
    }

    fn extends(&self) -> &EnvironmentExtends {
        &self.extends
    }

    fn runner_registry(&self) -> &RunnerRegistry {
        &self.runner_registry
    }

    fn debug_registry(&self) -> &DebugRegistry {
        &self.debug_registry
    }
}

#[async_trait]
impl Resolver for Environment {
    async fn resolve(&self, component_url: &str) -> Result<ResolvedComponent, ResolverError> {
        let parent = self.parent.upgrade().map_err(|_| ResolverError::SchemeNotRegistered)?;
        match self.resolver_registry.resolve(component_url).await {
            Err(ResolverError::SchemeNotRegistered) => match &self.extends {
                EnvironmentExtends::Realm => match parent {
                    ExtendedInstance::Component(parent) => {
                        parent.environment.resolve(component_url).await
                    }
                    ExtendedInstance::AboveRoot(_) => {
                        unreachable!("root env can't extend")
                    }
                },
                EnvironmentExtends::None => Err(ResolverError::SchemeNotRegistered),
            },
            result => result,
        }
    }
}

#[cfg(test)]
mod tests {
    use {
        super::*,
        crate::config::RuntimeConfig,
        crate::model::{
            binding::Binder,
            component::BindReason,
            error::ModelError,
            model::{Model, ModelParams},
            testing::{
                mocks::MockResolver,
                test_helpers::{
                    ChildDeclBuilder, CollectionDeclBuilder, ComponentDeclBuilder,
                    EnvironmentDeclBuilder,
                },
            },
        },
        ::routing::error::ComponentInstanceError,
        cm_rust::{CapabilityName, RegistrationSource, RunnerRegistration},
        maplit::hashmap,
        matches::assert_matches,
        moniker::AbsoluteMoniker,
        std::{collections::HashMap, sync::Weak},
    };

    #[test]
    fn test_from_decl() {
        let component = ComponentInstance::new_root(
            Environment::empty(),
            Weak::new(),
            Weak::new(),
            "test:///root".to_string(),
        );
        let environment = Environment::from_decl(
            &component,
            &EnvironmentDeclBuilder::new()
                .name("env")
                .extends(fsys::EnvironmentExtends::None)
                .stop_timeout(1234)
                .build(),
        );
        assert_matches!(environment.parent, WeakExtendedInstance::Component(_));

        let environment = Environment::from_decl(
            &component,
            &EnvironmentDeclBuilder::new()
                .name("env")
                .extends(fsys::EnvironmentExtends::Realm)
                .build(),
        );
        assert_matches!(environment.parent, WeakExtendedInstance::Component(_));

        let environment = Environment::from_decl(
            &component,
            &EnvironmentDeclBuilder::new()
                .name("env")
                .extends(fsys::EnvironmentExtends::None)
                .stop_timeout(1234)
                .add_debug_registration(cm_rust::DebugRegistration::Protocol(
                    cm_rust::DebugProtocolRegistration {
                        source_name: "source_name".into(),
                        target_name: "target_name".into(),
                        source: RegistrationSource::Parent,
                    },
                ))
                .build(),
        );
        let expected_debug_capability: HashMap<CapabilityName, DebugRegistration> = hashmap! {
            "target_name".into() =>
            DebugRegistration {
                source_name: "source_name".into(),
                source: RegistrationSource::Parent,
            }
        };
        assert_eq!(environment.debug_registry.debug_capabilities, expected_debug_capability);
    }

    // Each component declares an environment for their child that inherits from the component's
    // environment. The leaf component should be able to access the resolvers of the root.
    #[fuchsia::test]
    async fn test_inherit_root() -> Result<(), ModelError> {
        let runner_reg = RunnerRegistration {
            source: RegistrationSource::Parent,
            source_name: "test-src".into(),
            target_name: "test".into(),
        };
        let runners: HashMap<cm_rust::CapabilityName, RunnerRegistration> = hashmap! {
            "test".into() => runner_reg.clone()
        };

        let debug_reg = DebugRegistration {
            source_name: "source_name".into(),
            source: RegistrationSource::Self_,
        };

        let debug_capabilities: HashMap<cm_rust::CapabilityName, DebugRegistration> = hashmap! {
            "target_name".into() => debug_reg.clone()
        };
        let debug_registry = DebugRegistry { debug_capabilities };

        let mut resolver = MockResolver::new();
        resolver.add_component(
            "root",
            ComponentDeclBuilder::new_empty_component()
                .add_child(ChildDeclBuilder::new().name("a").url("test:///a").environment("env_a"))
                .add_environment(
                    EnvironmentDeclBuilder::new()
                        .name("env_a")
                        .extends(fsys::EnvironmentExtends::Realm),
                )
                .build(),
        );
        resolver.add_component(
            "a",
            ComponentDeclBuilder::new_empty_component()
                .add_child(ChildDeclBuilder::new().name("b").url("test:///b").environment("env_b"))
                .add_environment(
                    EnvironmentDeclBuilder::new()
                        .name("env_b")
                        .extends(fsys::EnvironmentExtends::Realm),
                )
                .build(),
        );
        resolver.add_component("b", ComponentDeclBuilder::new_empty_component().build());
        let resolvers = {
            let mut registry = ResolverRegistry::new();
            registry.register("test".to_string(), Box::new(resolver));
            registry
        };

        let top_instance = Arc::new(ComponentManagerInstance::new(vec![]));
        let model = Model::new(ModelParams {
            runtime_config: Arc::new(RuntimeConfig::default()),
            root_component_url: "test:///root".to_string(),
            root_environment: Environment::new_root(
                &top_instance,
                RunnerRegistry::new(runners),
                resolvers,
                debug_registry,
            ),
            top_instance,
        })
        .await
        .unwrap();
        let component = model.bind(&vec!["a:0", "b:0"].into(), &BindReason::Eager).await?;
        assert_eq!(component.component_url, "test:///b");

        let registered_runner =
            component.environment.get_registered_runner(&"test".into()).unwrap();
        assert_matches!(registered_runner, Some((ExtendedInstance::AboveRoot(_), r)) if r == runner_reg);
        assert_matches!(component.environment.get_registered_runner(&"foo".into()), Ok(None));

        let debug_capability =
            component.environment.get_debug_capability(&"target_name".into()).unwrap();
        assert_matches!(debug_capability, Some((ExtendedInstance::AboveRoot(_), None, d)) if d == debug_reg);
        assert_matches!(component.environment.get_debug_capability(&"foo".into()), Ok(None));

        Ok(())
    }

    // A component declares an environment that inherits from realm, and the realm's environment
    // added something that should be available in the component's realm.
    #[fuchsia::test]
    async fn test_inherit_parent() -> Result<(), ModelError> {
        let runner_reg = RunnerRegistration {
            source: RegistrationSource::Parent,
            source_name: "test-src".into(),
            target_name: "test".into(),
        };
        let runners: HashMap<CapabilityName, RunnerRegistration> = hashmap! {
            "test".into() => runner_reg.clone()
        };

        let debug_reg = DebugRegistration {
            source_name: "source_name".into(),
            source: RegistrationSource::Parent,
        };

        let mut resolver = MockResolver::new();
        resolver.add_component(
            "root",
            ComponentDeclBuilder::new_empty_component()
                .add_child(ChildDeclBuilder::new().name("a").url("test:///a").environment("env_a"))
                .add_environment(
                    EnvironmentDeclBuilder::new()
                        .name("env_a")
                        .extends(fsys::EnvironmentExtends::Realm)
                        .add_runner(RunnerRegistration {
                            source: RegistrationSource::Parent,
                            source_name: "test-src".into(),
                            target_name: "test".into(),
                        })
                        .add_debug_registration(cm_rust::DebugRegistration::Protocol(
                            cm_rust::DebugProtocolRegistration {
                                source_name: "source_name".into(),
                                target_name: "target_name".into(),
                                source: RegistrationSource::Parent,
                            },
                        )),
                )
                .build(),
        );
        resolver.add_component(
            "a",
            ComponentDeclBuilder::new_empty_component()
                .add_child(ChildDeclBuilder::new().name("b").url("test:///b").environment("env_b"))
                .add_environment(
                    EnvironmentDeclBuilder::new()
                        .name("env_b")
                        .extends(fsys::EnvironmentExtends::Realm),
                )
                .build(),
        );
        resolver.add_component("b", ComponentDeclBuilder::new_empty_component().build());
        let resolvers = {
            let mut registry = ResolverRegistry::new();
            registry.register("test".to_string(), Box::new(resolver));
            registry
        };

        let top_instance = Arc::new(ComponentManagerInstance::new(vec![]));
        let model = Model::new(ModelParams {
            runtime_config: Arc::new(RuntimeConfig::default()),
            root_component_url: "test:///root".to_string(),
            root_environment: Environment::new_root(
                &top_instance,
                RunnerRegistry::new(runners),
                resolvers,
                DebugRegistry::default(),
            ),
            top_instance,
        })
        .await?;
        let component = model.bind(&vec!["a:0", "b:0"].into(), &BindReason::Eager).await?;
        assert_eq!(component.component_url, "test:///b");

        let registered_runner =
            component.environment.get_registered_runner(&"test".into()).unwrap();
        assert_matches!(registered_runner, Some((ExtendedInstance::Component(c), r))
            if r == runner_reg && c.abs_moniker == AbsoluteMoniker::root());
        assert_matches!(component.environment.get_registered_runner(&"foo".into()), Ok(None));

        let debug_capability =
            component.environment.get_debug_capability(&"target_name".into()).unwrap();
        assert_matches!(debug_capability, Some((ExtendedInstance::Component(c), Some(_), d))
            if d == debug_reg && c.abs_moniker == AbsoluteMoniker::root());
        assert_matches!(component.environment.get_debug_capability(&"foo".into()), Ok(None));

        Ok(())
    }

    // A component in a collection declares an environment that inherits from realm, and the
    // realm's environment added something that should be available in the component's realm.
    #[fuchsia::test]
    async fn test_inherit_in_collection() -> Result<(), ModelError> {
        let runner_reg = RunnerRegistration {
            source: RegistrationSource::Parent,
            source_name: "test-src".into(),
            target_name: "test".into(),
        };
        let runners: HashMap<CapabilityName, RunnerRegistration> = hashmap! {
            "test".into() => runner_reg.clone()
        };

        let debug_reg = DebugRegistration {
            source_name: "source_name".into(),
            source: RegistrationSource::Parent,
        };

        let mut resolver = MockResolver::new();
        resolver.add_component(
            "root",
            ComponentDeclBuilder::new_empty_component()
                .add_child(ChildDeclBuilder::new().name("a").url("test:///a").environment("env_a"))
                .add_environment(
                    EnvironmentDeclBuilder::new()
                        .name("env_a")
                        .extends(fsys::EnvironmentExtends::Realm)
                        .add_runner(RunnerRegistration {
                            source: RegistrationSource::Parent,
                            source_name: "test-src".into(),
                            target_name: "test".into(),
                        })
                        .add_debug_registration(cm_rust::DebugRegistration::Protocol(
                            cm_rust::DebugProtocolRegistration {
                                source_name: "source_name".into(),
                                target_name: "target_name".into(),
                                source: RegistrationSource::Parent,
                            },
                        )),
                )
                .build(),
        );
        resolver.add_component(
            "a",
            ComponentDeclBuilder::new_empty_component()
                .add_collection(
                    CollectionDeclBuilder::new_transient_collection("coll").environment("env_b"),
                )
                .add_environment(
                    EnvironmentDeclBuilder::new()
                        .name("env_b")
                        .extends(fsys::EnvironmentExtends::Realm),
                )
                .build(),
        );
        resolver.add_component("b", ComponentDeclBuilder::new_empty_component().build());
        let resolvers = {
            let mut registry = ResolverRegistry::new();
            registry.register("test".to_string(), Box::new(resolver));
            registry
        };

        let top_instance = Arc::new(ComponentManagerInstance::new(vec![]));
        let model = Model::new(ModelParams {
            runtime_config: Arc::new(RuntimeConfig::default()),
            root_component_url: "test:///root".to_string(),
            root_environment: Environment::new_root(
                &top_instance,
                RunnerRegistry::new(runners),
                resolvers,
                DebugRegistry::default(),
            ),
            top_instance,
        })
        .await?;
        // Add instance to collection.
        {
            let parent = model.bind(&vec!["a:0"].into(), &BindReason::Eager).await?;
            let child_decl = ChildDeclBuilder::new_lazy_child("b").build();
            parent
                .add_dynamic_child("coll".into(), &child_decl)
                .await
                .expect("failed to add child");
        }
        let component = model.bind(&vec!["a:0", "coll:b:1"].into(), &BindReason::Eager).await?;
        assert_eq!(component.component_url, "test:///b");

        let registered_runner =
            component.environment.get_registered_runner(&"test".into()).unwrap();
        assert_matches!(registered_runner, Some((ExtendedInstance::Component(c), r))
            if r == runner_reg && c.abs_moniker == AbsoluteMoniker::root());
        assert_matches!(component.environment.get_registered_runner(&"foo".into()), Ok(None));

        let debug_capability =
            component.environment.get_debug_capability(&"target_name".into()).unwrap();
        assert_matches!(debug_capability, Some((ExtendedInstance::Component(c), Some(n), d))
            if d == debug_reg && n == "env_a" && c.abs_moniker == AbsoluteMoniker::root());
        assert_matches!(component.environment.get_debug_capability(&"foo".into()), Ok(None));

        Ok(())
    }

    // One of the components does not declare or specify an environment for the leaf child. The
    // leaf child component should still be able to access the resolvers of the root, as an
    // implicit inheriting environment is assumed.
    #[fuchsia::test]
    async fn test_auto_inheritance() -> Result<(), ModelError> {
        let runner_reg = RunnerRegistration {
            source: RegistrationSource::Parent,
            source_name: "test-src".into(),
            target_name: "test".into(),
        };
        let runners: HashMap<CapabilityName, RunnerRegistration> = hashmap! {
            "test".into() => runner_reg.clone()
        };

        let debug_reg = DebugRegistration {
            source_name: "source_name".into(),
            source: RegistrationSource::Parent,
        };

        let debug_capabilities: HashMap<CapabilityName, DebugRegistration> = hashmap! {
            "target_name".into() => debug_reg.clone()
        };
        let debug_registry = DebugRegistry { debug_capabilities };

        let mut resolver = MockResolver::new();
        resolver.add_component(
            "root",
            ComponentDeclBuilder::new_empty_component()
                .add_child(ChildDeclBuilder::new().name("a").url("test:///a").environment("env_a"))
                .add_environment(
                    EnvironmentDeclBuilder::new()
                        .name("env_a")
                        .extends(fsys::EnvironmentExtends::Realm),
                )
                .build(),
        );
        resolver.add_component(
            "a",
            ComponentDeclBuilder::new_empty_component()
                .add_child(ChildDeclBuilder::new().name("b").url("test:///b"))
                .build(),
        );
        resolver.add_component("b", ComponentDeclBuilder::new_empty_component().build());
        let resolvers = {
            let mut registry = ResolverRegistry::new();
            registry.register("test".to_string(), Box::new(resolver));
            registry
        };

        let top_instance = Arc::new(ComponentManagerInstance::new(vec![]));
        let model = Model::new(ModelParams {
            runtime_config: Arc::new(RuntimeConfig::default()),
            root_component_url: "test:///root".to_string(),
            root_environment: Environment::new_root(
                &top_instance,
                RunnerRegistry::new(runners),
                resolvers,
                debug_registry,
            ),
            top_instance,
        })
        .await
        .unwrap();

        let component = model.bind(&vec!["a:0", "b:0"].into(), &BindReason::Eager).await?;
        assert_eq!(component.component_url, "test:///b");

        let registered_runner =
            component.environment.get_registered_runner(&"test".into()).unwrap();
        assert_matches!(registered_runner, Some((ExtendedInstance::AboveRoot(_), r)) if r == runner_reg);
        assert_matches!(component.environment.get_registered_runner(&"foo".into()), Ok(None));

        let debug_capability =
            component.environment.get_debug_capability(&"target_name".into()).unwrap();
        assert_matches!(debug_capability, Some((ExtendedInstance::AboveRoot(_), None, d)) if d == debug_reg);
        assert_matches!(component.environment.get_debug_capability(&"foo".into()), Ok(None));

        Ok(())
    }

    // One of the components declares an environment that does not inherit from the realm. This
    // means that any child components of this component cannot be resolved.
    #[fuchsia::test]
    async fn test_resolver_no_inheritance() -> Result<(), ModelError> {
        let mut resolver = MockResolver::new();
        resolver.add_component(
            "root",
            ComponentDeclBuilder::new_empty_component()
                .add_child(ChildDeclBuilder::new().name("a").url("test:///a").environment("env_a"))
                .add_environment(
                    EnvironmentDeclBuilder::new()
                        .name("env_a")
                        .extends(fsys::EnvironmentExtends::Realm),
                )
                .build(),
        );
        resolver.add_component(
            "a",
            ComponentDeclBuilder::new_empty_component()
                .add_child(ChildDeclBuilder::new().name("b").url("test:///b").environment("env_b"))
                .add_environment(
                    EnvironmentDeclBuilder::new()
                        .name("env_b")
                        .extends(fsys::EnvironmentExtends::None)
                        .stop_timeout(1234),
                )
                .build(),
        );
        resolver.add_component("b", ComponentDeclBuilder::new_empty_component().build());
        let registry = {
            let mut registry = ResolverRegistry::new();
            registry.register("test".to_string(), Box::new(resolver));
            registry
        };
        let top_instance = Arc::new(ComponentManagerInstance::new(vec![]));
        let model = Model::new(ModelParams {
            runtime_config: Arc::new(RuntimeConfig::default()),
            root_component_url: "test:///root".to_string(),
            root_environment: Environment::new_root(
                &top_instance,
                RunnerRegistry::default(),
                registry,
                DebugRegistry::default(),
            ),
            top_instance,
        })
        .await?;
        assert_matches!(
            model.bind(&vec!["a:0", "b:0"].into(), &BindReason::Eager).await,
            Err(ModelError::ComponentInstanceError {
                err: ComponentInstanceError::ResolveFailed { .. }
            })
        );
        Ok(())
    }
}
