// 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::{
        error::ModelError,
        realm::{Realm, WeakRealm},
        resolver::{Resolver, ResolverError, ResolverFut, ResolverRegistry},
    },
    fidl_fuchsia_sys2 as fsys,
    std::{collections::HashMap, sync::Arc, time::Duration},
};

/// 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 {
    /// The parent that created or inherited the environment.
    parent: Option<WeakRealm>,
    /// 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,
    /// The deadline for runners to respond to `ComponentController.Stop` calls.
    stop_timeout: Duration,
}

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

/// How this environment extends its parent's.
#[derive(Debug, Clone)]
pub enum EnvironmentExtends {
    /// This environment extends the environment of its parent's.
    Realm,
    /// This environment was created from scratch.
    None,
}

impl From<fsys::EnvironmentExtends> for EnvironmentExtends {
    fn from(e: fsys::EnvironmentExtends) -> Self {
        match e {
            fsys::EnvironmentExtends::Realm => Self::Realm,
            fsys::EnvironmentExtends::None => Self::None,
        }
    }
}

impl Environment {
    /// Creates a new empty environment without a parent.
    pub fn empty() -> Environment {
        Environment {
            parent: None,
            extends: EnvironmentExtends::None,
            runner_registry: RunnerRegistry::default(),
            resolver_registry: ResolverRegistry::new(),
            stop_timeout: DEFAULT_STOP_TIMEOUT,
        }
    }

    /// Creates a new root environment with a resolver registry and no parent.
    pub fn new_root(
        runner_registry: RunnerRegistry,
        resolver_registry: ResolverRegistry,
    ) -> Environment {
        Environment {
            parent: None,
            extends: EnvironmentExtends::None,
            runner_registry,
            resolver_registry,
            stop_timeout: DEFAULT_STOP_TIMEOUT,
        }
    }

    /// Creates an environment from `env_decl`, using `parent` as the parent realm.
    pub fn from_decl(parent: &Arc<Realm>, env_decl: &cm_rust::EnvironmentDecl) -> Environment {
        Environment {
            parent: Some(parent.into()),
            extends: env_decl.extends.into(),
            runner_registry: RunnerRegistry::from_decl(&env_decl.runners),
            resolver_registry: ResolverRegistry::from_decl(&env_decl.resolvers, parent),
            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<Realm>) -> Environment {
        Environment {
            parent: Some(parent.into()),
            extends: EnvironmentExtends::Realm,
            runner_registry: RunnerRegistry::default(),
            resolver_registry: ResolverRegistry::new(),
            stop_timeout: parent.environment.stop_timeout(),
        }
    }

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

    /// Returns the runner registered to `name` and the realm that created the environment the
    /// runner was registered to (`None` for component manager's realm). Returns `None` if there
    /// was no match.
    pub fn get_registered_runner(
        &self,
        name: &cm_rust::CapabilityName,
    ) -> Result<Option<(Option<Arc<Realm>>, RunnerRegistration)>, ModelError> {
        let parent = self.parent.as_ref().map(|p| p.upgrade()).transpose()?;
        match self.runner_registry.get_runner(name) {
            Some(reg) => Ok(Some((parent, reg.clone()))),
            None => match self.extends {
                EnvironmentExtends::Realm => {
                    parent.unwrap().environment.get_registered_runner(name)
                }
                EnvironmentExtends::None => {
                    return Ok(None);
                }
            },
        }
    }
}

impl Resolver for Environment {
    fn resolve<'a>(&'a self, component_url: &'a str) -> ResolverFut<'a> {
        Box::pin(async move {
            match self.resolver_registry.resolve(component_url).await {
                Err(ResolverError::SchemeNotRegistered) => match &self.extends {
                    EnvironmentExtends::Realm => {
                        self.parent
                            .as_ref()
                            .unwrap()
                            .upgrade()
                            .map_err(|_| ResolverError::SchemeNotRegistered)?
                            .environment
                            .resolve(component_url)
                            .await
                    }
                    EnvironmentExtends::None => Err(ResolverError::SchemeNotRegistered),
                },
                result => result,
            }
        })
    }
}

/// The set of runners available in a realm's environment.
///
/// [`RunnerRegistration`]: fidl_fuchsia_sys2::RunnerRegistration
pub struct RunnerRegistry {
    runners: HashMap<cm_rust::CapabilityName, RunnerRegistration>,
}

impl RunnerRegistry {
    pub fn default() -> Self {
        Self { runners: HashMap::new() }
    }

    pub fn new(runners: HashMap<cm_rust::CapabilityName, RunnerRegistration>) -> Self {
        Self { runners }
    }

    pub fn from_decl(regs: &Vec<cm_rust::RunnerRegistration>) -> Self {
        let mut runners = HashMap::new();
        for reg in regs {
            runners.insert(
                reg.target_name.clone(),
                RunnerRegistration {
                    source_name: reg.source_name.clone(),
                    source: reg.source.clone(),
                },
            );
        }
        Self { runners }
    }
    pub fn get_runner(&self, name: &cm_rust::CapabilityName) -> Option<&RunnerRegistration> {
        self.runners.get(name)
    }
}

/// A single runner registered in an environment.
///
/// [`RunnerRegistration`]: fidl_fuchsia_sys2::RunnerRegistration
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct RunnerRegistration {
    pub source: cm_rust::RegistrationSource,
    pub source_name: cm_rust::CapabilityName,
}

#[cfg(test)]
mod tests {
    use {
        super::*,
        crate::config::RuntimeConfig,
        crate::model::{
            binding::Binder,
            error::ModelError,
            model::{Model, ModelParams},
            realm::BindReason,
            testing::{
                mocks::MockResolver,
                test_helpers::{
                    ChildDeclBuilder, CollectionDeclBuilder, ComponentDeclBuilder,
                    EnvironmentDeclBuilder,
                },
            },
        },
        fuchsia_async as fasync,
        maplit::hashmap,
        matches::assert_matches,
        moniker::AbsoluteMoniker,
        std::sync::Weak,
    };

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

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

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

        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 model = Model::new(ModelParams {
            runtime_config: Arc::new(RuntimeConfig::default()),
            root_component_url: "test:///root".to_string(),
            root_environment: Environment::new_root(RunnerRegistry::new(runners), resolvers),
            namespace_capabilities: vec![],
        })
        .await
        .unwrap();
        let realm = model.bind(&vec!["a:0", "b:0"].into(), &BindReason::Eager).await?;
        assert_eq!(realm.component_url, "test:///b");

        let registered_runner = realm.environment.get_registered_runner(&"test".into()).unwrap();
        assert_matches!(registered_runner.as_ref(), Some((None, r)) if r == &runner_reg);
        assert_matches!(realm.environment.get_registered_runner(&"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.
    #[fasync::run_singlethreaded(test)]
    async fn test_inherit_parent() -> Result<(), ModelError> {
        let runner_reg = RunnerRegistration {
            source: cm_rust::RegistrationSource::Parent,
            source_name: "test-src".into(),
        };
        let runners: HashMap<cm_rust::CapabilityName, RunnerRegistration> = hashmap! {
            "test".into() => runner_reg.clone()
        };

        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(cm_rust::RunnerRegistration {
                            source: cm_rust::RegistrationSource::Parent,
                            source_name: "test-src".into(),
                            target_name: "test".into(),
                        }),
                )
                .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 model = Model::new(ModelParams {
            runtime_config: Arc::new(RuntimeConfig::default()),
            root_component_url: "test:///root".to_string(),
            root_environment: Environment::new_root(RunnerRegistry::new(runners), resolvers),
            namespace_capabilities: vec![],
        })
        .await?;
        let realm = model.bind(&vec!["a:0", "b:0"].into(), &BindReason::Eager).await?;
        assert_eq!(realm.component_url, "test:///b");

        let registered_runner = realm.environment.get_registered_runner(&"test".into()).unwrap();
        assert_matches!(registered_runner.as_ref(), Some((Some(_), r)) if r == &runner_reg);
        let parent_moniker = &registered_runner.unwrap().0.unwrap().abs_moniker;
        assert_eq!(parent_moniker, &AbsoluteMoniker::root());
        assert_matches!(realm.environment.get_registered_runner(&"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.
    #[fasync::run_singlethreaded(test)]
    async fn test_inherit_in_collection() -> Result<(), ModelError> {
        let runner_reg = RunnerRegistration {
            source: cm_rust::RegistrationSource::Parent,
            source_name: "test-src".into(),
        };
        let runners: HashMap<cm_rust::CapabilityName, RunnerRegistration> = hashmap! {
            "test".into() => runner_reg.clone()
        };

        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(cm_rust::RunnerRegistration {
                            source: cm_rust::RegistrationSource::Parent,
                            source_name: "test-src".into(),
                            target_name: "test".into(),
                        }),
                )
                .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 model = Model::new(ModelParams {
            runtime_config: Arc::new(RuntimeConfig::default()),
            root_component_url: "test:///root".to_string(),
            root_environment: Environment::new_root(RunnerRegistry::new(runners), resolvers),
            namespace_capabilities: vec![],
        })
        .await?;
        // Add instance to collection.
        {
            let parent_realm = model.bind(&vec!["a:0"].into(), &BindReason::Eager).await?;
            let child_decl = ChildDeclBuilder::new_lazy_child("b").build();
            parent_realm
                .add_dynamic_child("coll".into(), &child_decl)
                .await
                .expect("failed to add child");
        }
        let realm = model.bind(&vec!["a:0", "coll:b:1"].into(), &BindReason::Eager).await?;
        assert_eq!(realm.component_url, "test:///b");

        let registered_runner = realm.environment.get_registered_runner(&"test".into()).unwrap();
        assert_matches!(registered_runner.as_ref(), Some((Some(_), r)) if r == &runner_reg);
        let parent_moniker = &registered_runner.unwrap().0.unwrap().abs_moniker;
        assert_eq!(parent_moniker, &AbsoluteMoniker::root());
        assert_matches!(realm.environment.get_registered_runner(&"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 realm, as an
    // implicit inheriting environment is assumed.
    #[fasync::run_singlethreaded(test)]
    async fn test_auto_inheritance() -> Result<(), ModelError> {
        let runner_reg = RunnerRegistration {
            source: cm_rust::RegistrationSource::Parent,
            source_name: "test-src".into(),
        };
        let runners: HashMap<cm_rust::CapabilityName, RunnerRegistration> = hashmap! {
            "test".into() => runner_reg.clone()
        };

        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 model = Model::new(ModelParams {
            runtime_config: Arc::new(RuntimeConfig::default()),
            root_component_url: "test:///root".to_string(),
            root_environment: Environment::new_root(RunnerRegistry::new(runners), resolvers),
            namespace_capabilities: vec![],
        })
        .await
        .unwrap();

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

        let registered_runner = realm.environment.get_registered_runner(&"test".into()).unwrap();
        assert_matches!(registered_runner.as_ref(), Some((None, r)) if r == &runner_reg);
        assert_matches!(realm.environment.get_registered_runner(&"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.
    #[fasync::run_singlethreaded(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 model = Model::new(ModelParams {
            runtime_config: Arc::new(RuntimeConfig::default()),
            root_component_url: "test:///root".to_string(),
            root_environment: Environment::new_root(RunnerRegistry::default(), registry),
            namespace_capabilities: vec![],
        })
        .await?;
        assert_matches!(
            model.bind(&vec!["a:0", "b:0"].into(), &BindReason::Eager).await,
            Err(ModelError::ResolverError { .. })
        );
        Ok(())
    }
}
