// 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 {
    anyhow::{format_err, Error},
    fidl::endpoints::{create_endpoints, create_proxy, Proxy, ServiceMarker},
    fidl_fuchsia_io as io, fidl_fuchsia_io_test as io_test, fidl_fuchsia_sys2 as fsys,
    fuchsia_async as fasync, fuchsia_zircon as zx,
    fuchsia_zircon::Status,
    futures::StreamExt,
    io_conformance::io1_request_logger_factory::Io1RequestLoggerFactory,
};

pub async fn connect_to_harness() -> Result<io_test::Io1HarnessProxy, Error> {
    // Connect to the realm to get acccess to the outgoing directory for the harness.
    let (client, server) = zx::Channel::create()?;
    fuchsia_component::client::connect_channel_to_service::<fsys::RealmMarker>(server)?;
    let mut realm = fsys::RealmSynchronousProxy::new(client);
    // fs_test is the name of the child component defined in the manifest.
    let mut child_ref = fsys::ChildRef { name: "fs_test".to_string(), collection: None };
    let (client, server) = zx::Channel::create()?;
    realm
        .bind_child(
            &mut child_ref,
            fidl::endpoints::ServerEnd::<io::DirectoryMarker>::new(server),
            zx::Time::INFINITE,
        )?
        .map_err(|e| format_err!("Failed to bind to child: {:#?}", e))?;

    let exposed_dir = io::DirectoryProxy::new(fidl::AsyncChannel::from_channel(client)?);
    let proxy = fuchsia_component::client::connect_to_protocol_at_dir_root::<
        io_test::Io1HarnessMarker,
    >(&exposed_dir)
    .await?;
    Ok(proxy)
}

/// Helper function to open the desired node in the root folder. Only use this
/// if testing something other than the open call directly.
async fn open_node<T: ServiceMarker>(
    dir: &io::DirectoryProxy,
    flags: u32,
    mode: u32,
    path: &str,
) -> T::Proxy {
    let flags = flags | io::OPEN_FLAG_DESCRIBE;
    let (node_proxy, node_server) = create_proxy::<io::NodeMarker>().expect("Cannot create proxy.");
    dir.open(flags, mode, path, node_server).expect("Cannot open node");

    // Listening to make sure open call succeeded.
    {
        let mut events = node_proxy.take_event_stream();
        let io::NodeEvent::OnOpen_ { s, info: _ } =
            events.next().await.expect("OnOpen event not received").expect("no fidl error");
        assert_eq!(Status::from_raw(s), Status::OK);
    }
    T::Proxy::from_channel(node_proxy.into_channel().expect("Cannot convert node proxy to channel"))
}

/// Constant representing the aggregate of all io.fidl rights.
// TODO(fxbug.dev/59574): Add io::OPEN_RIGHT_EXECUTABLE and io::OPEN_RIGHT_ADMIN back here once
// they are supported by rustvfs (or alternatively add tests to check they *are not* supported for
// all implementations, or add a config flag to allow controlling this as a test configuration
// option).
const ALL_RIGHTS: u32 = io::OPEN_RIGHT_READABLE | io::OPEN_RIGHT_WRITABLE;

/// Returns a list of flag combinations to test. Returns a vector of the aggregate of
/// every constant flag and every combination of variable flags.
/// Ex. build_flag_combinations([100], [010, 001]) would return [100, 110, 101, 111]
/// for flags expressed as binary. We exclude the no rights case as that is an
/// invalid argument in most cases. Ex. build_flag_combinations([], [010, 001])
/// would return [010, 001, 011] without the 000 case.
/// All flags passed in must be single bit values.
fn build_flag_combinations(constant_flags: &[u32], variable_flags: &[u32]) -> Vec<u32> {
    // Initial check to make sure all flags are single bit.
    for flag in constant_flags {
        assert_eq!(flag & (flag - 1), 0);
    }
    for flag in variable_flags {
        assert_eq!(flag & (flag - 1), 0);
    }
    let mut base_flag = 0;
    for flag in constant_flags {
        base_flag |= flag;
    }
    let mut vec = vec![base_flag];
    for flag in variable_flags {
        let length = vec.len();
        for i in 0..length {
            vec.push(vec[i] | flag);
        }
    }
    vec.retain(|element| *element != 0);

    vec
}

fn root_directory(flags: u32, entries: Vec<io_test::DirectoryEntry>) -> io_test::Directory {
    // Convert the simple vector of entries into the convoluted FIDL field type.
    let entries: Vec<Option<Box<io_test::DirectoryEntry>>> =
        entries.into_iter().map(|e| Some(Box::new(e))).collect();
    io_test::Directory { name: None, flags: Some(flags), entries: Some(entries) }
}

fn directory(
    name: &str,
    flags: u32,
    entries: Vec<io_test::DirectoryEntry>,
) -> io_test::DirectoryEntry {
    let mut dir = root_directory(flags, entries);
    dir.name = Some(name.to_string());
    io_test::DirectoryEntry::Directory(dir)
}

fn file(name: &str, flags: u32, contents: Vec<u8>) -> io_test::DirectoryEntry {
    io_test::DirectoryEntry::File(io_test::File {
        name: Some(name.to_string()),
        flags: Some(flags),
        contents: Some(contents),
    })
}

// Example test to start up a v2 component harness to test when opening a path that goes through a
// remote mount point, the server forwards the request to the remote correctly.
#[fasync::run_singlethreaded(test)]
async fn open_remote_directory_test() {
    let harness = connect_to_harness().await.expect("Could not setup harness connection.");

    let config = harness.get_config().await.expect("Could not get config from harness.");
    if config.no_remote_dir.unwrap_or_default() {
        return;
    }

    let (remote_dir_client, remote_dir_server) =
        create_endpoints::<io::DirectoryMarker>().expect("Cannot create endpoints.");

    let remote_name = "remote_directory";

    // Request an extra directory connection from the harness to use as the remote,
    // and interpose the requests from the server under test to this remote.
    let (logger, mut rx) = Io1RequestLoggerFactory::new();
    let remote_dir_server =
        logger.get_logged_directory(remote_name.to_string(), remote_dir_server).await;
    let root = root_directory(io::OPEN_RIGHT_READABLE | io::OPEN_RIGHT_WRITABLE, vec![]);
    harness.get_directory(root, remote_dir_server).expect("Cannot get empty remote directory.");

    let (test_dir_proxy, test_dir_server) =
        create_proxy::<io::DirectoryMarker>().expect("Cannot create proxy.");
    harness
        .get_directory_with_remote_directory(
            remote_dir_client,
            remote_name,
            io::OPEN_RIGHT_READABLE | io::OPEN_RIGHT_WRITABLE,
            test_dir_server,
        )
        .expect("Cannot get test harness directory.");

    let (_remote_dir_proxy, remote_dir_server) =
        create_proxy::<io::NodeMarker>().expect("Cannot create proxy.");
    test_dir_proxy
        .open(io::OPEN_RIGHT_READABLE, io::MODE_TYPE_DIRECTORY, remote_name, remote_dir_server)
        .expect("Cannot open remote directory.");

    // Wait on an open call to the interposed remote directory.
    let open_request_string = rx.next().await.expect("Local tx/rx channel was closed");

    // TODO(fxbug.dev/45613):: Bare-metal testing against returned request string. We need
    // to find a more ergonomic return format.
    assert_eq!(open_request_string, "remote_directory flags:1, mode:16384, path:.");
}

#[fasync::run_singlethreaded(test)]
async fn file_read_with_sufficient_rights() {
    let harness = connect_to_harness().await.expect("Could not setup harness connection.");

    let filename = "testing.txt";

    let constant_flags = [io::OPEN_RIGHT_READABLE];
    let variable_flags = [io::OPEN_RIGHT_WRITABLE];

    let file_flags_set = build_flag_combinations(&constant_flags, &variable_flags);
    for file_flags in file_flags_set {
        let root = root_directory(ALL_RIGHTS, vec![file(filename, file_flags, Vec::new())]);
        let (test_dir_proxy, test_dir_server) =
            create_proxy::<io::DirectoryMarker>().expect("Cannot create proxy.");
        harness
            .get_directory(root, test_dir_server)
            .expect("Cannot get remote directory with file.");

        let file =
            open_node::<io::FileMarker>(&test_dir_proxy, file_flags, io::MODE_TYPE_FILE, filename)
                .await;
        let (status, _data) = file.read(0).await.expect("Read failed.");
        assert_eq!(Status::from_raw(status), Status::OK);
    }
}

#[fasync::run_singlethreaded(test)]
async fn file_read_with_insufficient_rights() {
    let harness = connect_to_harness().await.expect("Could not setup harness connection.");

    let filename = "testing.txt";

    let constant_flags = [];
    let variable_flags = [io::OPEN_RIGHT_WRITABLE];

    let file_flags_set = build_flag_combinations(&constant_flags, &variable_flags);
    for file_flags in file_flags_set {
        let root = root_directory(ALL_RIGHTS, vec![file(filename, file_flags, Vec::new())]);
        let (test_dir_proxy, test_dir_server) =
            create_proxy::<io::DirectoryMarker>().expect("Cannot create proxy.");
        harness
            .get_directory(root, test_dir_server)
            .expect("Cannot get remote directory with file.");

        let file =
            open_node::<io::FileMarker>(&test_dir_proxy, file_flags, io::MODE_TYPE_FILE, filename)
                .await;
        let (status, _data) = file.read(0).await.expect("Read failed.");
        assert_ne!(Status::from_raw(status), Status::OK);
    }
}

#[fasync::run_singlethreaded(test)]
async fn file_read_at_with_sufficient_rights() {
    let harness = connect_to_harness().await.expect("Could not setup harness connection.");

    let filename = "testing.txt";

    let constant_flags = [io::OPEN_RIGHT_READABLE];
    let variable_flags = [io::OPEN_RIGHT_WRITABLE];

    let file_flags_set = build_flag_combinations(&constant_flags, &variable_flags);
    for file_flags in file_flags_set {
        let root = root_directory(ALL_RIGHTS, vec![file(filename, file_flags, Vec::new())]);
        let (test_dir_proxy, test_dir_server) =
            create_proxy::<io::DirectoryMarker>().expect("Cannot create proxy.");
        harness
            .get_directory(root, test_dir_server)
            .expect("Cannot get remote directory with file.");

        let file =
            open_node::<io::FileMarker>(&test_dir_proxy, file_flags, io::MODE_TYPE_FILE, filename)
                .await;
        let (status, _data) = file.read_at(0, 0).await.expect("Read at failed.");
        assert_eq!(Status::from_raw(status), Status::OK);
    }
}

#[fasync::run_singlethreaded(test)]
async fn file_read_at_with_insufficient_rights() {
    let harness = connect_to_harness().await.expect("Could not setup harness connection.");

    let filename = "testing.txt";

    let constant_flags = [];
    let variable_flags = [io::OPEN_RIGHT_WRITABLE];

    let file_flags_set = build_flag_combinations(&constant_flags, &variable_flags);
    for file_flags in file_flags_set {
        let root = root_directory(ALL_RIGHTS, vec![file(filename, file_flags, Vec::new())]);
        let (test_dir_proxy, test_dir_server) =
            create_proxy::<io::DirectoryMarker>().expect("Cannot create proxy.");
        harness
            .get_directory(root, test_dir_server)
            .expect("Cannot get remote directory with file.");

        let file =
            open_node::<io::FileMarker>(&test_dir_proxy, file_flags, io::MODE_TYPE_FILE, filename)
                .await;
        let (status, _data) = file.read_at(0, 0).await.expect("Read at failed.");
        assert_ne!(Status::from_raw(status), Status::OK);
    }
}

#[fasync::run_singlethreaded(test)]
async fn file_write_with_sufficient_rights() {
    let harness = connect_to_harness().await.expect("Could not setup harness connection.");

    let filename = "testing.txt";

    let constant_flags = [io::OPEN_RIGHT_WRITABLE];
    let variable_flags = [io::OPEN_RIGHT_READABLE];

    let file_flags_set = build_flag_combinations(&constant_flags, &variable_flags);
    for file_flags in file_flags_set {
        let root = root_directory(ALL_RIGHTS, vec![file(filename, file_flags, Vec::new())]);
        let (test_dir_proxy, test_dir_server) =
            create_proxy::<io::DirectoryMarker>().expect("Cannot create proxy.");
        harness
            .get_directory(root, test_dir_server)
            .expect("Cannot get remote directory with file.");

        let file =
            open_node::<io::FileMarker>(&test_dir_proxy, file_flags, io::MODE_TYPE_FILE, filename)
                .await;
        let (status, _actual) = file.write("".as_bytes()).await.expect("Failed to write file");
        assert_eq!(Status::from_raw(status), Status::OK);
    }
}

#[fasync::run_singlethreaded(test)]
async fn file_write_with_insufficient_rights() {
    let harness = connect_to_harness().await.expect("Could not setup harness connection.");

    let filename = "testing.txt";

    let constant_flags = [];
    let variable_flags = [io::OPEN_RIGHT_READABLE];

    let file_flags_set = build_flag_combinations(&constant_flags, &variable_flags);
    for file_flags in file_flags_set {
        let root = root_directory(ALL_RIGHTS, vec![file(filename, file_flags, Vec::new())]);
        let (test_dir_proxy, test_dir_server) =
            create_proxy::<io::DirectoryMarker>().expect("Cannot create proxy.");
        harness
            .get_directory(root, test_dir_server)
            .expect("Cannot get remote directory with file.");

        let file =
            open_node::<io::FileMarker>(&test_dir_proxy, file_flags, io::MODE_TYPE_FILE, filename)
                .await;
        let (status, _actual) = file.write("".as_bytes()).await.expect("Failed to write file");
        assert_ne!(Status::from_raw(status), Status::OK);
    }
}

#[fasync::run_singlethreaded(test)]
async fn file_read_in_subdirectory() {
    let harness = connect_to_harness().await.expect("Could not setup harness connection.");

    let constant_flags = [io::OPEN_RIGHT_READABLE];
    let variable_flags = [io::OPEN_RIGHT_WRITABLE];

    let file_flags_set = build_flag_combinations(&constant_flags, &variable_flags);
    for file_flags in file_flags_set {
        let root = root_directory(
            ALL_RIGHTS,
            vec![directory(
                "subdir",
                ALL_RIGHTS,
                vec![file("testing.txt", file_flags, Vec::new())],
            )],
        );
        let (test_dir_proxy, test_dir_server) =
            create_proxy::<io::DirectoryMarker>().expect("Cannot create proxy.");
        harness
            .get_directory(root, test_dir_server)
            .expect("Cannot get remote directory with file.");

        let file = open_node::<io::FileMarker>(
            &test_dir_proxy,
            file_flags,
            io::MODE_TYPE_FILE,
            "subdir/testing.txt",
        )
        .await;
        let (status, _data) = file.read(0).await.expect("Read failed.");
        assert_eq!(Status::from_raw(status), Status::OK);
    }
}

#[cfg(test)]
mod tests {
    use super::build_flag_combinations;

    #[test]
    fn test_build_flag_combinations() {
        let constant_flags = [0b100];
        let variable_flags = [0b010, 0b001];
        let generated_combinations = build_flag_combinations(&constant_flags, &variable_flags);
        let expected_result = [0b100, 0b110, 0b101, 0b111];
        assert_eq!(generated_combinations, expected_result);
    }

    #[test]
    fn test_build_flag_combinations_without_empty_rights() {
        let constant_flags = [];
        let variable_flags = [0b010, 0b001];
        let generated_combinations = build_flag_combinations(&constant_flags, &variable_flags);
        let expected_result = [0b010, 0b001, 0b011];
        assert_eq!(generated_combinations, expected_result);
    }
}
