// 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.

mod test_utils;

use {
    anyhow::{Context, Result},
    fidl_fuchsia_driver_development as fdd, fidl_fuchsia_driver_framework as fdf,
    fidl_fuchsia_driver_test as fdt,
    fuchsia_async::{self as fasync},
    fuchsia_component_test::{RealmBuilder, RealmInstance},
    fuchsia_driver_test::{DriverTestRealmBuilder, DriverTestRealmInstance},
    fuchsia_zircon_status as zx_status,
};

const SAMPLE_DRIVER_URL: &str = "fuchsia-boot:///#meta/sample-driver.cm";
const SAMPLE_DRIVER_LIBNAME: &str = "fuchsia-boot:///#driver/sample-driver.so";
const PARENT_DRIVER_URL: &str = "fuchsia-boot:///#meta/test-parent-sys.cm";
const PARENT_DRIVER_LIBNAME: &str = "fuchsia-boot:///#driver/test-parent-sys.so";
const FAKE_DRIVER_URL: &str = "fuchsia-boot:///#meta/driver-test-realm-fake-driver.cm";

fn get_no_protocol_dfv2_property_list() -> Option<[fdf::NodeProperty; 2]> {
    Some([
        fdf::NodeProperty {
            key: Some(fdf::NodePropertyKey::IntValue(bind::ddk_bind_constants::BIND_PROTOCOL)),
            value: Some(fdf::NodePropertyValue::IntValue(0)),
            unknown_data: None,
            ..fdf::NodeProperty::EMPTY
        },
        fdf::NodeProperty {
            key: Some(fdf::NodePropertyKey::StringValue(String::from(
                "fuchsia.driver.framework.dfv2",
            ))),
            value: Some(fdf::NodePropertyValue::BoolValue(true)),
            unknown_data: None,
            ..fdf::NodeProperty::EMPTY
        },
    ])
}

fn get_test_parent_dfv2_property_list() -> Option<[fdf::NodeProperty; 2]> {
    Some([
        fdf::NodeProperty {
            key: Some(fdf::NodePropertyKey::IntValue(bind::ddk_bind_constants::BIND_PROTOCOL)),
            value: Some(fdf::NodePropertyValue::IntValue(bind_fuchsia_test::BIND_PROTOCOL_PARENT)),
            unknown_data: None,
            ..fdf::NodeProperty::EMPTY
        },
        fdf::NodeProperty {
            key: Some(fdf::NodePropertyKey::StringValue(String::from(
                "fuchsia.driver.framework.dfv2",
            ))),
            value: Some(fdf::NodePropertyValue::BoolValue(true)),
            unknown_data: None,
            ..fdf::NodeProperty::EMPTY
        },
    ])
}

fn assert_not_found_error(error: fidl::Error) {
    if let fidl::Error::ClientChannelClosed { status, protocol_name: _ } = error {
        assert_eq!(status, zx_status::Status::NOT_FOUND);
    } else {
        panic!("Expcted ClientChannelClosed error");
    }
}

fn send_get_device_info_request(
    service: &fdd::DriverDevelopmentProxy,
    device_filter: &[&str],
) -> Result<fdd::DeviceInfoIteratorProxy> {
    let (iterator, iterator_server) =
        fidl::endpoints::create_proxy::<fdd::DeviceInfoIteratorMarker>()?;

    service
        .get_device_info(&mut device_filter.iter().map(|i| *i), iterator_server)
        .context("FIDL call to get device info failed")?;

    Ok(iterator)
}

async fn get_device_info(
    service: &fdd::DriverDevelopmentProxy,
    device_filter: &[&str],
) -> Result<Vec<fdd::DeviceInfo>> {
    let iterator = send_get_device_info_request(service, device_filter)?;

    let mut device_infos = Vec::new();
    loop {
        let mut device_info =
            iterator.get_next().await.context("FIDL call to get device info failed")?;
        if device_info.len() == 0 {
            break;
        }
        device_infos.append(&mut device_info);
    }
    Ok(device_infos)
}

fn send_get_driver_info_request(
    service: &fdd::DriverDevelopmentProxy,
    driver_filter: &[&str],
) -> Result<fdd::DriverInfoIteratorProxy> {
    let (iterator, iterator_server) =
        fidl::endpoints::create_proxy::<fdd::DriverInfoIteratorMarker>()?;

    service
        .get_driver_info(&mut driver_filter.iter().map(|i| *i), iterator_server)
        .context("FIDL call to get driver info failed")?;

    Ok(iterator)
}

async fn get_driver_info(
    service: &fdd::DriverDevelopmentProxy,
    driver_filter: &[&str],
) -> Result<Vec<fdd::DriverInfo>> {
    let iterator = send_get_driver_info_request(service, driver_filter)?;

    let mut driver_infos = Vec::new();
    loop {
        let mut driver_info =
            iterator.get_next().await.context("FIDL call to get driver info failed")?;
        if driver_info.len() == 0 {
            break;
        }
        driver_infos.append(&mut driver_info)
    }
    Ok(driver_infos)
}

async fn set_up_test_driver_realm(
    use_dfv2: bool,
) -> Result<(RealmInstance, fdd::DriverDevelopmentProxy)> {
    const ROOT_DRIVER_DFV2_URL: &str = PARENT_DRIVER_URL;

    let builder = RealmBuilder::new().await?;
    builder.driver_test_realm_setup().await?;
    let instance = builder.build().await?;

    let mut realm_args = fdt::RealmArgs::EMPTY;
    realm_args.use_driver_framework_v2 = Some(use_dfv2);
    if use_dfv2 {
        // DriverTestRealm attempts to bind the .so of test-parent-sys if not explicitly requested otherwise.
        realm_args.root_driver = Some(ROOT_DRIVER_DFV2_URL.to_owned());
    }
    instance.driver_test_realm_start(realm_args).await?;

    let driver_dev =
        instance.root.connect_to_protocol_at_exposed_dir::<fdd::DriverDevelopmentMarker>()?;

    // Make sure we wait until all the drivers are bound before returning.
    let dev = instance.driver_test_realm_connect_to_dev()?;
    let _ = device_watcher::recursive_wait_and_open_node(&dev, "sys/test/sample_driver").await;

    Ok((instance, driver_dev))
}

fn assert_contains_driver_url(driver_infos: &Vec<fdd::DriverInfo>, expected_driver_url: &str) {
    assert!(driver_infos
        .iter()
        .find(|driver_info| driver_info.url.as_ref().expect("Missing device URL")
            == expected_driver_url)
        .is_some());
}

// GetDriverInfo tests
// DFv1
#[fasync::run_singlethreaded(test)]
async fn test_get_driver_info_no_filter_dfv1() -> Result<()> {
    let (_instance, driver_dev) = set_up_test_driver_realm(false).await?;
    let driver_infos = get_driver_info(&driver_dev, &[]).await?;

    assert_eq!(driver_infos.len(), 3);
    assert_contains_driver_url(&driver_infos, SAMPLE_DRIVER_URL);
    assert_contains_driver_url(&driver_infos, PARENT_DRIVER_URL);
    assert_contains_driver_url(&driver_infos, FAKE_DRIVER_URL);
    Ok(())
}

#[fasync::run_singlethreaded(test)]
async fn test_get_driver_info_with_filter_dfv1() -> Result<()> {
    const DRIVER_FILTER: [&str; 1] = [SAMPLE_DRIVER_LIBNAME];

    let (_instance, driver_dev) = set_up_test_driver_realm(false).await?;
    let driver_infos = get_driver_info(&driver_dev, &DRIVER_FILTER).await?;

    assert_eq!(driver_infos.len(), 1);
    assert_contains_driver_url(&driver_infos, SAMPLE_DRIVER_URL);
    Ok(())
}

#[fasync::run_singlethreaded(test)]
async fn test_get_driver_info_with_mixed_filter_dfv1() -> Result<()> {
    const DRIVER_FILTER: [&str; 2] = [SAMPLE_DRIVER_URL, "foo"];

    let (_instance, driver_dev) = set_up_test_driver_realm(false).await?;
    let iterator = send_get_driver_info_request(&driver_dev, &DRIVER_FILTER)?;
    let res = iterator.get_next().await.expect_err("A driver should not be returned");

    assert_not_found_error(res);
    Ok(())
}

#[fasync::run_singlethreaded(test)]
async fn test_get_driver_info_with_incomplete_filter_dfv1() -> Result<()> {
    const DRIVER_FILTER: [&str; 1] = ["fuchsia-boot:///#driver/sample-driver"];

    let (_instance, driver_dev) = set_up_test_driver_realm(false).await?;
    let iterator = send_get_driver_info_request(&driver_dev, &DRIVER_FILTER)?;
    let res = iterator.get_next().await.expect_err("A driver should not be returned");

    assert_not_found_error(res);
    Ok(())
}

#[fasync::run_singlethreaded(test)]
async fn test_get_driver_info_not_found_filter_dfv1() -> Result<()> {
    const DRIVER_FILTER: [&str; 1] = ["foo"];

    let (_instance, driver_dev) = set_up_test_driver_realm(false).await?;
    let iterator = send_get_driver_info_request(&driver_dev, &DRIVER_FILTER)?;
    let res = iterator.get_next().await.expect_err("A driver should not be returned");

    assert_not_found_error(res);
    Ok(())
}

// DFv2
#[fasync::run_singlethreaded(test)]
async fn test_get_driver_info_no_filter_dfv2() -> Result<()> {
    let (_instance, driver_dev) = set_up_test_driver_realm(true).await?;
    let driver_infos = get_driver_info(&driver_dev, &[]).await?;

    assert_eq!(driver_infos.len(), 3);
    assert_contains_driver_url(&driver_infos, SAMPLE_DRIVER_URL);
    assert_contains_driver_url(&driver_infos, PARENT_DRIVER_URL);
    assert_contains_driver_url(&driver_infos, FAKE_DRIVER_URL);
    Ok(())
}

#[fasync::run_singlethreaded(test)]
async fn test_get_driver_info_with_filter_dfv2() -> Result<()> {
    const DRIVER_FILTER: [&str; 1] = [SAMPLE_DRIVER_LIBNAME];

    let (_instance, driver_dev) = set_up_test_driver_realm(true).await?;
    let driver_infos = get_driver_info(&driver_dev, &DRIVER_FILTER).await?;

    assert_eq!(driver_infos.len(), 1);
    assert_contains_driver_url(&driver_infos, SAMPLE_DRIVER_URL);
    Ok(())
}

#[fasync::run_singlethreaded(test)]
async fn test_get_driver_info_with_duplicate_filter_dfv2() -> Result<()> {
    const DRIVER_FILTER: [&str; 2] = [SAMPLE_DRIVER_LIBNAME, SAMPLE_DRIVER_LIBNAME];

    let (_instance, driver_dev) = set_up_test_driver_realm(true).await?;
    let driver_infos = get_driver_info(&driver_dev, &DRIVER_FILTER).await?;

    assert_eq!(driver_infos.len(), 1);
    assert_contains_driver_url(&driver_infos, SAMPLE_DRIVER_URL);

    Ok(())
}

#[fasync::run_singlethreaded(test)]
async fn test_get_driver_info_with_mixed_filter_dfv2() -> Result<()> {
    const DRIVER_FILTER: [&str; 2] = [SAMPLE_DRIVER_LIBNAME, "foo"];

    let (_instance, driver_dev) = set_up_test_driver_realm(true).await?;
    let driver_infos = get_driver_info(&driver_dev, &DRIVER_FILTER).await?;

    assert_eq!(driver_infos.len(), 1);
    assert_contains_driver_url(&driver_infos, SAMPLE_DRIVER_URL);

    Ok(())
}

#[fasync::run_singlethreaded(test)]
async fn test_get_driver_info_with_incomplete_filter_dfv2() -> Result<()> {
    const DRIVER_FILTER: [&str; 1] = ["fuchsia-boot:///#meta/sample-driver"];

    let (_instance, driver_dev) = set_up_test_driver_realm(true).await?;
    let driver_infos = get_driver_info(&driver_dev, &DRIVER_FILTER).await?;

    assert!(driver_infos.is_empty());
    Ok(())
}

#[fasync::run_singlethreaded(test)]
async fn test_get_driver_info_not_found_filter_dfv2() -> Result<()> {
    const DRIVER_FILTER: [&str; 1] = ["foo"];

    let (_instance, driver_dev) = set_up_test_driver_realm(true).await?;
    let driver_infos = get_driver_info(&driver_dev, &DRIVER_FILTER).await?;

    assert!(driver_infos.is_empty());
    Ok(())
}

// GetDeviceInfo tests
// DFv1
#[fasync::run_singlethreaded(test)]
async fn test_get_device_info_no_filter_dfv1() -> Result<()> {
    let (_instance, driver_dev) = set_up_test_driver_realm(false).await?;
    let device_infos = get_device_info(&driver_dev, &[]).await?;

    let device_nodes = test_utils::create_device_topology(device_infos);
    assert_eq!(device_nodes.len(), 1);

    let root_sys_test = &device_nodes[0];
    assert_eq!(
        root_sys_test.info.topological_path.as_ref().expect("DFv1 device missing topological path"),
        "/dev/sys/test"
    );
    assert!(root_sys_test.info.moniker.is_none());
    assert!(root_sys_test.info.node_property_list.is_none());
    assert_eq!(
        root_sys_test
            .info
            .bound_driver_libname
            .as_ref()
            .expect("DFv1 driver missing bound driver libname"),
        PARENT_DRIVER_LIBNAME
    );
    assert_eq!(root_sys_test.num_children, 1);
    assert_eq!(root_sys_test.child_nodes.len(), 1);

    let sample_driver = &root_sys_test.child_nodes[0];
    assert_eq!(
        sample_driver.info.topological_path.as_ref().expect("DFv1 device missing topological path"),
        "/dev/sys/test/sample_driver"
    );
    assert!(sample_driver.info.moniker.is_none());
    assert!(sample_driver.info.node_property_list.is_none());
    assert_eq!(
        sample_driver
            .info
            .bound_driver_libname
            .as_ref()
            .expect("DFv1 driver missing bound driver libname"),
        SAMPLE_DRIVER_LIBNAME
    );
    assert_eq!(sample_driver.num_children, 0);
    assert!(sample_driver.child_nodes.is_empty());
    Ok(())
}

#[fasync::run_singlethreaded(test)]
async fn test_get_device_info_with_filter_dfv1() -> Result<()> {
    const DEVICE_FILTER: [&str; 1] = ["sys/test"];

    let (_instance, driver_dev) = set_up_test_driver_realm(false).await?;
    let device_infos = get_device_info(&driver_dev, &DEVICE_FILTER).await?;

    let device_nodes = test_utils::create_device_topology(device_infos);
    assert_eq!(device_nodes.len(), 1);

    let sys_test = &device_nodes[0];
    assert_eq!(
        sys_test.info.topological_path.as_ref().expect("DFv1 device missing topological path"),
        "/dev/sys/test"
    );
    assert!(sys_test.info.moniker.is_none());
    assert!(sys_test.info.node_property_list.is_none());
    assert_eq!(
        sys_test
            .info
            .bound_driver_libname
            .as_ref()
            .expect("DFv1 driver missing bound driver libname"),
        PARENT_DRIVER_LIBNAME
    );
    assert_eq!(sys_test.num_children, 1);
    assert!(sys_test.child_nodes.is_empty());
    Ok(())
}

#[fasync::run_singlethreaded(test)]
async fn test_get_device_info_with_duplicate_filter_dfv1() -> Result<()> {
    const DEVICE_FILTER: [&str; 2] = ["sys/test/sample_driver", "sys/test/sample_driver"];

    let (_instance, driver_dev) = set_up_test_driver_realm(false).await?;
    let device_infos = get_device_info(&driver_dev, &DEVICE_FILTER).await?;

    let device_nodes = test_utils::create_device_topology(device_infos);
    assert_eq!(device_nodes.len(), 2);

    let sample_driver = &device_nodes[0];
    assert_eq!(
        sample_driver.info.topological_path.as_ref().expect("DFv1 device missing topological path"),
        "/dev/sys/test/sample_driver"
    );
    assert!(sample_driver.info.moniker.is_none());
    assert!(sample_driver.info.node_property_list.is_none());
    assert_eq!(
        sample_driver
            .info
            .bound_driver_libname
            .as_ref()
            .expect("DFv1 driver missing bound driver libname"),
        SAMPLE_DRIVER_LIBNAME
    );
    assert!(sample_driver.child_nodes.is_empty());

    let sample_driver = &device_nodes[1];
    assert_eq!(
        sample_driver.info.topological_path.as_ref().expect("DFv1 device missing topological path"),
        "/dev/sys/test/sample_driver"
    );
    assert!(sample_driver.info.moniker.is_none());
    assert!(sample_driver.info.node_property_list.is_none());
    assert_eq!(
        sample_driver
            .info
            .bound_driver_libname
            .as_ref()
            .expect("DFv1 driver missing bound driver libname"),
        SAMPLE_DRIVER_LIBNAME
    );
    assert_eq!(sample_driver.num_children, 0);
    assert!(sample_driver.child_nodes.is_empty());
    Ok(())
}

#[fasync::run_singlethreaded(test)]
async fn test_get_device_info_with_incomplete_filter_dfv1() -> Result<()> {
    const DEVICE_FILTER: [&str; 1] = ["sys/test/sample"];

    let (_instance, driver_dev) = set_up_test_driver_realm(false).await?;
    let iterator = send_get_device_info_request(&driver_dev, &DEVICE_FILTER)?;
    let res = iterator.get_next().await.expect_err("A device should not be returned");

    assert_not_found_error(res);
    Ok(())
}

#[fasync::run_singlethreaded(test)]
async fn test_get_device_info_not_found_filter_dfv1() -> Result<()> {
    const DEVICE_FILTER: [&str; 1] = ["foo"];

    let (_instance, driver_dev) = set_up_test_driver_realm(false).await?;
    let iterator = send_get_device_info_request(&driver_dev, &DEVICE_FILTER)?;
    let res = iterator.get_next().await.expect_err("A device should not be returned");

    assert_not_found_error(res);
    Ok(())
}

// DFv2
#[fasync::run_singlethreaded(test)]
async fn test_get_device_info_no_filter_dfv2() -> Result<()> {
    let (_instance, driver_dev) = set_up_test_driver_realm(true).await?;
    let device_infos = get_device_info(&driver_dev, &[]).await?;

    let device_nodes = test_utils::create_device_topology(device_infos);
    assert_eq!(device_nodes.len(), 1);

    let root = &device_nodes[0];
    assert_eq!(root.info.moniker.as_ref().expect("DFv2 node missing moniker"), "root");
    assert!(root.info.bound_driver_libname.is_none(), "DFv2 node specified bound driver libname");
    assert_eq!(
        root.info.bound_driver_url.as_ref().expect("DFv2 node missing driver URL"),
        PARENT_DRIVER_URL
    );
    assert!(root.info.property_list.is_none());
    assert!(root.info.node_property_list.is_none());
    assert_eq!(root.num_children, 1);
    assert_eq!(root.child_nodes.len(), 1);

    let sys = &root.child_nodes[0];
    assert_eq!(sys.info.moniker.as_ref().expect("DFv2 node missing moniker"), "root.sys");
    assert!(sys.info.bound_driver_libname.is_none(), "DFv2 node specified bound driver libname");
    assert!(sys.info.bound_driver_url.is_none());
    assert_eq!(
        sys.info.node_property_list.as_ref().map(|x| x.as_slice()),
        get_no_protocol_dfv2_property_list().as_ref().map(|x| x.as_slice())
    );
    assert_eq!(sys.num_children, 1);
    assert_eq!(sys.child_nodes.len(), 1);

    let test = &sys.child_nodes[0];
    assert_eq!(test.info.moniker.as_ref().expect("DFv2 node missing moniker"), "root.sys.test");
    assert!(test.info.bound_driver_libname.is_none(), "DFv2 node specified bound driver libname");
    assert_eq!(
        test.info.bound_driver_url.as_ref().expect("DFv2 node missing driver URL"),
        SAMPLE_DRIVER_URL
    );
    assert_eq!(
        test.info.node_property_list.as_ref().map(|x| x.as_slice()),
        get_test_parent_dfv2_property_list().as_ref().map(|x| x.as_slice())
    );
    Ok(())
}

#[fasync::run_singlethreaded(test)]
async fn test_get_device_info_with_filter_dfv2() -> Result<()> {
    const DEVICE_FILTER: [&str; 1] = ["root.sys.test"];

    let (_instance, driver_dev) = set_up_test_driver_realm(true).await?;
    let device_infos = get_device_info(&driver_dev, &DEVICE_FILTER).await?;

    let device_nodes = test_utils::create_device_topology(device_infos);
    assert_eq!(device_nodes.len(), 1);

    let root_sys_test = &device_nodes[0];
    assert_eq!(
        root_sys_test.info.moniker.as_ref().expect("DFv2 node missing moniker"),
        "root.sys.test"
    );
    assert!(
        root_sys_test.info.bound_driver_libname.is_none(),
        "DFv2 node specified bound driver libname"
    );
    assert_eq!(
        root_sys_test.info.bound_driver_url.as_ref().expect("DFv2 node missing driver URL"),
        SAMPLE_DRIVER_URL
    );
    assert_eq!(
        root_sys_test.info.node_property_list.as_ref().map(|x| x.as_slice()),
        get_test_parent_dfv2_property_list().as_ref().map(|x| x.as_slice())
    );
    assert!(root_sys_test.child_nodes.is_empty());
    Ok(())
}

#[fasync::run_singlethreaded(test)]
async fn test_get_device_info_with_duplicate_filter_dfv2() -> Result<()> {
    const DEVICE_FILTER: [&str; 2] = ["root.sys.test", "root.sys.test"];

    let (_instance, driver_dev) = set_up_test_driver_realm(true).await?;
    let device_infos = get_device_info(&driver_dev, &DEVICE_FILTER).await?;

    let device_nodes = test_utils::create_device_topology(device_infos);
    assert_eq!(device_nodes.len(), 1);

    let root_sys_test = &device_nodes[0];
    assert_eq!(
        root_sys_test.info.moniker.as_ref().expect("DFv2 node missing moniker"),
        "root.sys.test"
    );
    assert!(
        root_sys_test.info.bound_driver_libname.is_none(),
        "DFv2 node specified bound driver libname"
    );
    assert_eq!(
        root_sys_test.info.bound_driver_url.as_ref().expect("DFv2 node missing driver URL"),
        SAMPLE_DRIVER_URL
    );
    assert_eq!(
        root_sys_test.info.node_property_list.as_ref().map(|x| x.as_slice()),
        get_test_parent_dfv2_property_list().as_ref().map(|x| x.as_slice())
    );
    assert!(root_sys_test.child_nodes.is_empty());
    Ok(())
}

#[fasync::run_singlethreaded(test)]
async fn test_get_device_info_with_incomplete_filter_dfv2() -> Result<()> {
    const DEVICE_FILTER: [&str; 1] = ["root.sys.te"];

    let (_instance, driver_dev) = set_up_test_driver_realm(true).await?;
    let device_infos = get_device_info(&driver_dev, &DEVICE_FILTER).await?;

    assert!(device_infos.is_empty());
    Ok(())
}

#[fasync::run_singlethreaded(test)]
async fn test_get_device_info_not_found_filter_dfv2() -> Result<()> {
    const DEVICE_FILTER: [&str; 1] = ["foo"];

    let (_instance, driver_dev) = set_up_test_driver_realm(true).await?;
    let device_infos = get_device_info(&driver_dev, &DEVICE_FILTER).await?;

    assert!(device_infos.is_empty());
    Ok(())
}
