// 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::Error,
    fidl_fidl_test_components as ftest, fidl_fuchsia_io as fio, fuchsia_async as fasync,
    fuchsia_component::server::ServiceFs,
    futures::{StreamExt, TryStreamExt},
    std::io,
};

/// Contains all the information required to verify that a particular path contains some set of
/// rights.
struct RightsTestCase {
    path: &'static str,
    rights: u32,
}

impl RightsTestCase {
    /// Constructs a new rights test case.
    fn new(path: &'static str, rights: u32) -> RightsTestCase {
        RightsTestCase { path: path, rights: rights }
    }

    /// Returns every right not available for this path.
    fn unavailable_rights(&self) -> Vec<u32> {
        let all_rights = [
            fio::OPEN_RIGHT_READABLE,
            fio::OPEN_RIGHT_WRITABLE,
            fio::OPEN_RIGHT_EXECUTABLE,
            fio::OPEN_RIGHT_ADMIN,
        ];

        let mut unavailable_rights: Vec<u32> = vec![];
        for right_to_check in all_rights.iter() {
            if *right_to_check | self.rights != self.rights {
                unavailable_rights.push(*right_to_check);
            }
        }
        unavailable_rights
    }

    /// Verifies that the rights are correctly implemented for the type.
    fn verify(&self) -> io::Result<()> {
        fdio::open_fd(self.path, self.rights)?;
        for invalid_right in self.unavailable_rights() {
            if let Ok(_) = fdio::open_fd(self.path, invalid_right) {
                return Err(io::Error::new(
                    io::ErrorKind::Other,
                    format!(
                        "Path: {} with rights: {} was opened with invalid rights {}",
                        self.path, self.rights, invalid_right
                    ),
                ));
            }
        }
        return Ok(());
    }
}

#[fasync::run_singlethreaded]
async fn main() {
    let mut fs = ServiceFs::new_local();
    fs.dir("svc").add_fidl_service(move |stream| {
        fasync::spawn_local(async move {
            run_trigger_service(stream).await.expect("failed to run trigger service");
        });
    });
    fs.take_and_serve_directory_handle().expect("failed to serve outgoing directory");
    fs.collect::<()>().await;
}

async fn run_trigger_service(mut stream: ftest::TriggerRequestStream) -> Result<(), Error> {
    while let Some(event) = stream.try_next().await? {
        handle_trigger(event).await;
    }
    Ok(())
}

async fn handle_trigger(event: ftest::TriggerRequest) {
    let ftest::TriggerRequest::Run { responder } = event;
    let tests = [
        RightsTestCase::new("/read_only", fio::OPEN_RIGHT_READABLE),
        RightsTestCase::new("/read_write", fio::OPEN_RIGHT_READABLE | fio::OPEN_RIGHT_WRITABLE),
        RightsTestCase::new("/read_write_dup", fio::OPEN_RIGHT_READABLE | fio::OPEN_RIGHT_WRITABLE),
        RightsTestCase::new("/read_exec", fio::OPEN_RIGHT_READABLE | fio::OPEN_RIGHT_EXECUTABLE),
        RightsTestCase::new("/read_admin", fio::OPEN_RIGHT_READABLE | fio::OPEN_RIGHT_ADMIN),
        RightsTestCase::new("/read_only_after_scoped", fio::OPEN_RIGHT_READABLE),
    ];
    for test_case in tests.iter() {
        if let Err(test_failure) = test_case.verify() {
            responder
                .send(&format!(
                    "Directory rights test failed: {} - {}",
                    test_case.path, test_failure,
                ))
                .expect("failed to send trigger response");
            return;
        }
    }
    responder.send("All tests passed").expect("failed to send trigger response");
}
