// Copyright 2022 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::{anyhow, Context, Result},
    fidl_fuchsia_driver_development as fdd, fidl_fuchsia_driver_framework as fdf,
    fidl_fuchsia_driver_registrar as fdr, fidl_fuchsia_driver_test as fdt,
    fuchsia_async::{self as fasync},
    fuchsia_component_test::{RealmBuilder, RealmInstance},
    fuchsia_driver_test::{DriverTestRealmBuilder, DriverTestRealmInstance},
};

// Note: The component manifest name is the same for FAKE_DRIVER_URL and EPHEMERAL_FAKE_DRIVER_URL
// One is in bootfs, the other is through a package url.
// This is because we can't have an in-tree driver not be in bootfs.
//
// In this test the ephemeral one is still being resolved through the package resolver and going
// through the register flow when we call the register api.
//
// Unfortunately this means that we can't test whether we can load the new driver using
// bind_all_unbound_nodes.
// Whatever the bind rules on the fake driver are will be identical to the one in bootfs
// and if there is a device that would bind to it, it would bind to the bootfs one first.
const SAMPLE_DRIVER_URL: &str = "fuchsia-boot:///dtr#meta/sample-driver.cm";
const PARENT_DRIVER_URL: &str = "fuchsia-boot:///dtr#meta/test-parent-sys.cm";
const FAKE_DRIVER_URL: &str = "fuchsia-boot:///dtr#meta/driver-test-realm-fake-driver.cm";
const EPHEMERAL_FAKE_DRIVER_URL: &str =
    "fuchsia-pkg://fuchsia.com/driver-test-realm-fake-driver#meta/driver-test-realm-fake-driver.cm";

async fn set_up_test_driver_realm(
) -> Result<(RealmInstance, fdd::ManagerProxy, fdr::DriverRegistrarProxy)> {
    const ROOT_DRIVER_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::default();
    // DriverTestRealm attempts to bind the .so of test-parent-sys if not explicitly requested otherwise.
    realm_args.root_driver = Some(ROOT_DRIVER_URL.to_owned());
    instance.driver_test_realm_start(realm_args).await?;

    let driver_dev = instance.root.connect_to_protocol_at_exposed_dir::<fdd::ManagerMarker>()?;
    let driver_registar =
        instance.root.connect_to_protocol_at_exposed_dir::<fdr::DriverRegistrarMarker>()?;

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

    Ok((instance, driver_dev, driver_registar))
}

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

    service
        .get_driver_info(driver_filter, iterator_server)
        .context("FIDL call to get driver info failed")?;

    Ok(iterator)
}

async fn get_driver_info(
    service: &fdd::ManagerProxy,
    driver_filter: &[String],
) -> Result<Vec<fdf::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)
}

fn assert_contains_driver_url(driver_infos: &Vec<fdf::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());
}

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

    // Before register we should have 3 drivers, the ones in bootfs.
    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);

    // Register the driver through a package url.
    driver_registrar
        .register(EPHEMERAL_FAKE_DRIVER_URL)
        .await
        .map_err(|e| anyhow!("Failed to call register driver: {}", e))?
        .map_err(|e| anyhow!("Failed to register driver with err: {}", e))?;

    // Now we should have 4 drivers, the original 3, plus the new ephemeral one.
    let driver_infos = get_driver_info(&driver_dev, &[]).await?;
    assert_eq!(driver_infos.len(), 4);
    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);
    assert_contains_driver_url(&driver_infos, EPHEMERAL_FAKE_DRIVER_URL);

    Ok(())
}
