// 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 {
    anyhow::{Context as _, Error},
    fidl::endpoints::{self, Proxy},
    fidl_fidl_test_components as ftest, fidl_fuchsia_component as fcomponent,
    fidl_fuchsia_io::{DirectoryMarker, DirectoryProxy, MODE_TYPE_SERVICE},
    fidl_fuchsia_sys2 as fsys, fuchsia_async as fasync,
    fuchsia_component::client,
    io_util::{self, OPEN_RIGHT_READABLE},
    std::path::PathBuf,
};

#[fasync::run_singlethreaded(test)]
async fn collections() {
    let realm = client::connect_to_service::<fsys::RealmMarker>()
        .expect("could not connect to Realm service");

    // Create a couple child components.
    for name in vec!["a", "b"] {
        let mut collection_ref = fsys::CollectionRef { name: "coll".to_string() };
        let child_decl = fsys::ChildDecl {
            name: Some(name.to_string()),
            url: Some(format!(
                "fuchsia-pkg://fuchsia.com/collections_integration_test#meta/trigger_{}.cm",
                name
            )),
            startup: Some(fsys::StartupMode::Lazy),
            environment: None,
            ..fsys::ChildDecl::EMPTY
        };
        realm
            .create_child(&mut collection_ref, child_decl)
            .await
            .expect(&format!("create_child {} failed", name))
            .expect(&format!("failed to create child {}", name));
    }

    let children = list_children(&realm).await.expect("failed to list children");
    assert_eq!("coll:a,coll:b", &children);

    // Bind to children, causing them to execute.
    for name in vec!["a", "b"] {
        let mut child_ref = new_child_ref(name, "coll");
        let (dir, server_end) = endpoints::create_proxy::<DirectoryMarker>().unwrap();
        realm
            .bind_child(&mut child_ref, server_end)
            .await
            .expect(&format!("bind_child {} failed", name))
            .expect(&format!("failed to bind to child {}", name));
        let trigger = open_trigger_svc(&dir).expect("failed to open trigger service");
        let out = trigger.run().await.expect(&format!("trigger {} failed", name));
        assert_eq!(out, format!("Triggered {}", name));
    }

    // Destroy one.
    {
        let mut child_ref = new_child_ref("a", "coll");
        realm
            .destroy_child(&mut child_ref)
            .await
            .expect("destroy_child a failed")
            .expect("failed to destroy child");
    }

    // Binding to destroyed child should fail.
    {
        let (_, server_end) = endpoints::create_proxy::<DirectoryMarker>().unwrap();
        let mut child_ref = new_child_ref("a", "coll");
        let res =
            realm.bind_child(&mut child_ref, server_end).await.expect("second bind_child a failed");
        let err = res.expect_err("expected bind_child a to fail");
        assert_eq!(err, fcomponent::Error::InstanceNotFound);
    }

    let children = list_children(&realm).await.expect("failed to list children");
    assert_eq!("coll:b", &children);

    // Recreate child (with different URL), and bind to it. Should work.
    {
        let mut collection_ref = fsys::CollectionRef { name: "coll".to_string() };
        let child_decl = fsys::ChildDecl {
            name: Some("a".to_string()),
            url: Some(
                "fuchsia-pkg://fuchsia.com/collections_integration_test#meta/trigger_realm.cm"
                    .to_string(),
            ),
            startup: Some(fsys::StartupMode::Lazy),
            environment: None,
            ..fsys::ChildDecl::EMPTY
        };
        realm
            .create_child(&mut collection_ref, child_decl)
            .await
            .expect("second create_child a failed")
            .expect("failed to create second child a");
    }
    {
        let (dir, server_end) = endpoints::create_proxy::<DirectoryMarker>().unwrap();
        let mut child_ref = new_child_ref("a", "coll");
        realm
            .bind_child(&mut child_ref, server_end)
            .await
            .expect("bind_child a failed")
            .expect("failed to bind to child a");
        let trigger = open_trigger_svc(&dir).expect("failed to open trigger service");
        let out = trigger.run().await.expect("second trigger a failed");
        assert_eq!(&out, "Triggered a");
    }

    let children = list_children(&realm).await.expect("failed to list children");
    assert_eq!("coll:a,coll:b", &children);
}

fn new_child_ref(name: &str, collection: &str) -> fsys::ChildRef {
    fsys::ChildRef { name: name.to_string(), collection: Some(collection.to_string()) }
}

async fn list_children(realm: &fsys::RealmProxy) -> Result<String, Error> {
    let (iterator_proxy, server_end) = endpoints::create_proxy().unwrap();
    let mut collection_ref = fsys::CollectionRef { name: "coll".to_string() };
    realm
        .list_children(&mut collection_ref, server_end)
        .await
        .expect("list_children failed")
        .expect("failed to list children");
    let res = iterator_proxy.next().await;
    let children = res.expect("failed to iterate over children");
    let children: Vec<_> = children
        .iter()
        .map(|c| format!("{}:{}", c.collection.as_ref().expect("no collection"), &c.name))
        .collect();
    Ok(children.join(","))
}

fn open_trigger_svc(dir: &DirectoryProxy) -> Result<ftest::TriggerProxy, Error> {
    let node_proxy = io_util::open_node(
        dir,
        &PathBuf::from("fidl.test.components.Trigger"),
        OPEN_RIGHT_READABLE,
        MODE_TYPE_SERVICE,
    )
    .context("failed to open trigger service")?;
    Ok(ftest::TriggerProxy::new(node_proxy.into_channel().unwrap()))
}
