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

/// Logs an error message if the passed in `result` is an error.
#[macro_export]
macro_rules! log_if_err {
    ($result:expr, $log_prefix:expr) => {
        if let Err(e) = $result.as_ref() {
            log::error!("{}: {}", $log_prefix, e);
        }
    };
}

/// Logs an error message if the provided `cond` evaluates to false. Also passes the same expression
/// and message into `debug_assert!`, which will panic if debug assertions are enabled.
#[macro_export]
macro_rules! log_if_false_and_debug_assert {
    ($cond:expr, $msg:expr) => {
        if !($cond) {
            log::error!($msg);
            debug_assert!($cond, $msg);
        }
    };
    ($cond:expr, $fmt:expr, $($arg:tt)+) => {
        if !($cond) {
            log::error!($fmt, $($arg)+);
            debug_assert!($cond, $fmt, $($arg)+);
        }
    };
}

#[cfg(test)]
mod log_err_with_debug_assert_tests {
    use crate::log_if_false_and_debug_assert;

    /// Tests that `log_if_false_and_debug_assert` panics for a false expression when debug
    /// assertions are enabled.
    #[test]
    #[should_panic(expected = "this will panic")]
    #[cfg(debug_assertions)]
    fn test_debug_assert() {
        log_if_false_and_debug_assert!(true, "this will not panic");
        log_if_false_and_debug_assert!(false, "this will panic");
    }

    /// Tests that `log_if_false_and_debug_assert` does not panic for a false expression when debug
    /// assertions are not enabled.
    #[test]
    #[cfg(not(debug_assertions))]
    fn test_non_debug_assert() {
        log_if_false_and_debug_assert!(true, "this will not panic");
        log_if_false_and_debug_assert!(false, "this will not panic either");
    }
}

/// Export the `connect_to_driver` function to be used throughout the crate.
pub use connect_to_driver::connect_to_driver;
mod connect_to_driver {
    use anyhow::{format_err, Error};
    use fidl::endpoints::Proxy as _;
    use fidl_fuchsia_io as fio;

    /// Returns a NodeProxy opened at `path`. The path is guaranteed to exist before the connection
    /// is opened.
    async fn connect_channel(path: &str) -> Result<fio::NodeProxy, Error> {
        device_watcher::recursive_wait_and_open_node(
            &fuchsia_fs::open_directory_in_namespace(
                "/dev",
                fio::OpenFlags::RIGHT_READABLE | fio::OpenFlags::RIGHT_WRITABLE,
            )?,
            path,
        )
        .await
    }

    /// Connects to the driver at `path`, returning a proxy of the specified type. The path is
    /// guaranteed to exist before the connection is opened.
    ///
    /// TODO(fxbug.dev/81378): factor this function out to a common library
    pub async fn connect_to_driver<T: fidl::endpoints::ProtocolMarker>(
        path: &str,
    ) -> Result<T::Proxy, Error> {
        match path.strip_prefix("/dev/") {
            Some(path) => fidl::endpoints::ClientEnd::<T>::new(
                connect_channel(path)
                    .await?
                    .into_channel()
                    .map_err(|_| format_err!("into_channel failed on NodeProxy"))?
                    .into_zx_channel(),
            )
            .into_proxy()
            .map_err(Into::into),
            None => Err(format_err!("Path must start with /dev/")),
        }
    }

    #[cfg(test)]
    mod tests {
        use super::*;
        use async_utils::PollExt as _;
        use fidl::endpoints::{create_proxy, Proxy, ServerEnd};
        use fidl_fuchsia_io as fio;
        use fuchsia_async as fasync;
        use futures::TryStreamExt as _;
        use std::sync::Arc;
        use vfs::{
            directory::entry::DirectoryEntry, directory::helper::DirectlyMutable,
            execution_scope::ExecutionScope, file::vmo::read_only_static, pseudo_directory,
        };

        fn bind_to_dev(dir: Arc<dyn DirectoryEntry>) {
            let (dir_proxy, dir_server) = create_proxy::<fio::DirectoryMarker>().unwrap();
            let scope = ExecutionScope::new();
            dir.open(
                scope,
                fio::OpenFlags::RIGHT_READABLE | fio::OpenFlags::RIGHT_WRITABLE,
                fio::MODE_TYPE_DIRECTORY,
                vfs::path::Path::dot(),
                ServerEnd::new(dir_server.into_channel()),
            );
            let ns = fdio::Namespace::installed().unwrap();
            ns.bind("/dev", dir_proxy.into_channel().unwrap().into_zx_channel()).unwrap();
        }

        /// Tests that `connect_to_driver` returns success for the valid existing path.
        #[fasync::run_singlethreaded(test)]
        async fn test_connect_to_driver_success() {
            bind_to_dev(pseudo_directory! {
                "class" => pseudo_directory!{
                    "thermal" => pseudo_directory! {
                        "000" => read_only_static("string beans")
                    }
                }
            });

            connect_to_driver::<fio::NodeMarker>("/dev/class/thermal/000").await.unwrap();
        }

        /// Tests that `connect_to_driver` doesn't return until the required path is added.
        #[test]
        fn test_connect_to_driver_late_add() {
            let mut executor = fasync::TestExecutor::new().unwrap();

            let thermal_dir = pseudo_directory! {
                "000" => read_only_static("string cheese (cheddar)")
            };
            bind_to_dev(pseudo_directory! {
                "class" => pseudo_directory!{
                    "thermal" => thermal_dir.clone()
                }
            });

            let connect_future =
                &mut Box::pin(connect_to_driver::<fio::NodeMarker>("/dev/class/thermal/001"));

            // The required path is initially not present
            assert!(executor.run_until_stalled(connect_future).is_pending());

            // Add the required path
            thermal_dir.add_entry("001", read_only_static("string cheese (mozzarella)")).unwrap();

            // Verify the wait future now returns successfully
            assert!(executor.run_until_stalled(connect_future).unwrap().is_ok());
        }

        /// Tests that `connect_to_driver` correctly waits even if the required parent directory
        /// does not yet exist.
        #[test]
        fn test_connect_to_driver_nonexistent_parent_dir() {
            let mut executor = fasync::TestExecutor::new().unwrap();

            bind_to_dev(pseudo_directory! {
                "class" => pseudo_directory!{
                    "cpu" => pseudo_directory! {
                        "000" => read_only_static("shoestring fries")
                    }
                }
            });

            assert!(executor
                .run_until_stalled(&mut Box::pin(connect_to_driver::<fio::NodeMarker>(
                    "/dev/class/thermal/000"
                )))
                .is_pending());
        }

        /// Tests that the proxy returned by `connect_to_driver` is usable for sending a FIDL
        /// request.
        #[fasync::run_singlethreaded(test)]
        async fn test_connect_to_driver_gives_usable_proxy() {
            use fidl_fuchsia_device as fdev;

            // Create a pseudo directory with a fuchsia.device.Controller FIDL server hosted at
            // class/fake_dev_controller and bind it to our /dev
            bind_to_dev(pseudo_directory! {
                "class" => pseudo_directory! {
                    "fake_dev_controller" => vfs::service::host(
                        move |mut stream: fdev::ControllerRequestStream| {
                            async move {
                                match stream.try_next().await.unwrap() {
                                    Some(fdev::ControllerRequest::GetCurrentPerformanceState {
                                        responder
                                    }) => {
                                        let _ = responder.send(8);
                                    }
                                    e => panic!("Unexpected request: {:?}", e),
                                }
                            }
                        }
                    )
                }
            });

            // Connect to the driver and call GetCurrentPerformanceState on it
            let result = crate::utils::connect_to_driver::<fdev::ControllerMarker>(
                "/dev/class/fake_dev_controller",
            )
            .await
            .expect("Failed to connect to driver")
            .get_current_performance_state()
            .await
            .expect("get_current_performance_state FIDL failed");

            // Verify we receive the expected result
            assert_eq!(result, 8);
        }

        /// Verifies that invalid arguments are rejected while valid ones are accepted.
        #[fasync::run_singlethreaded(test)]
        async fn test_connect_to_driver_valid_path() {
            bind_to_dev(pseudo_directory! {
                "class" => pseudo_directory!{
                    "cpu" => pseudo_directory! {
                        "000" => read_only_static("stringtown population 1")
                    }
                }
            });

            connect_to_driver::<fio::NodeMarker>("/svc/fake_service").await.unwrap_err();
            connect_to_driver::<fio::NodeMarker>("/dev/class/cpu/000").await.unwrap();
        }
    }
}

/// The number of nanoseconds since the system was powered on.
pub fn get_current_timestamp() -> crate::types::Nanoseconds {
    crate::types::Nanoseconds(fuchsia_async::Time::now().into_nanos())
}

use fidl_fuchsia_cobalt::HistogramBucket;

/// Convenient wrapper for creating and storing an integer histogram to use with Cobalt.
pub struct CobaltIntHistogram {
    /// Underlying histogram data storage.
    data: Vec<HistogramBucket>,

    /// Number of data values that have been added to the histogram.
    data_count: u32,

    /// Histogram configuration parameters.
    config: CobaltIntHistogramConfig,
}

/// Histogram configuration parameters used by CobaltIntHistogram.
pub struct CobaltIntHistogramConfig {
    pub floor: i64,
    pub num_buckets: u32,
    pub step_size: u32,
}

impl CobaltIntHistogram {
    /// Create a new CobaltIntHistogram.
    pub fn new(config: CobaltIntHistogramConfig) -> Self {
        Self { data: Self::new_vec(config.num_buckets), data_count: 0, config }
    }

    /// Create a new Vec<HistogramBucket> that represents the underlying histogram storage. Two
    /// extra buckets are added for underflow and overflow.
    fn new_vec(num_buckets: u32) -> Vec<HistogramBucket> {
        (0..num_buckets + 2).map(|i| HistogramBucket { index: i, count: 0 }).collect()
    }

    /// Add a data value to the histogram.
    pub fn add_data(&mut self, n: i64) {
        // Add one to index to account for underflow bucket at index 0
        let mut index = 1 + (n - self.config.floor) / self.config.step_size as i64;

        // Clamp index to 0 and self.data.len() - 1, which Cobalt uses for underflow and overflow,
        // respectively
        index = num_traits::clamp(index, 0, self.data.len() as i64 - 1);

        self.data[index as usize].count += 1;
        self.data_count += 1;
    }

    /// Get the number of data elements that have been added to the histogram.
    pub fn count(&self) -> u32 {
        self.data_count
    }

    /// Clear the histogram.
    pub fn clear(&mut self) {
        self.data = Self::new_vec(self.config.num_buckets);
        self.data_count = 0;
    }

    /// Get the underlying Vec<HistogramBucket> of the histogram.
    pub fn get_data(&self) -> Vec<HistogramBucket> {
        self.data.clone()
    }
}

// Finds all of the node config files under the test package's "/config/data" directory. The node
// config files are identified by a suffix of "node_config.json5". The function then calls the
// provided `test_config_file` function for each found config file, passing the JSON structure in as
// an argument. The function returns success if each call to `test_config_file` succeeds. Otherwise,
// the first error encountered is returned.
#[cfg(test)]
pub fn test_each_node_config_file(
    test_config_file: impl Fn(&Vec<serde_json::Value>) -> Result<(), anyhow::Error>,
) -> Result<(), anyhow::Error> {
    use anyhow::Context as _;
    use std::fs;

    let suffix = "node_config.json5";
    let config_files = fs::read_dir("/config/data")
        .unwrap()
        .filter(|f| f.as_ref().unwrap().file_name().to_str().unwrap().ends_with(suffix))
        .map(|f| {
            let path = f.unwrap().path();
            let file_path = path.to_str().unwrap().to_string();
            let contents = std::fs::read_to_string(&file_path).unwrap();
            let json = serde_json5::from_str(&contents)
                .expect(&format!("Failed to parse file {}", file_path));

            (file_path, json)
        })
        .collect::<Vec<_>>();
    assert!(config_files.len() > 0, "No config files found");

    for (file_path, config_file) in config_files {
        test_config_file(&config_file).context(format!("Failed for file {}", file_path))?;
    }

    Ok(())
}

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

    /// CobaltIntHistogram: tests that data added to the CobaltIntHistogram is correctly counted and
    /// bucketed.
    #[test]
    fn test_cobalt_histogram_data() {
        // Create the histogram and verify initial data count is 0
        let mut hist = CobaltIntHistogram::new(CobaltIntHistogramConfig {
            floor: 50,
            step_size: 10,
            num_buckets: 3,
        });
        assert_eq!(hist.count(), 0);

        // Add some arbitrary values, making sure some do not land on the bucket boundary to further
        // verify the bucketing logic
        hist.add_data(50);
        hist.add_data(65);
        hist.add_data(75);
        hist.add_data(79);

        // Verify the values were counted and bucketed properly
        assert_eq!(hist.count(), 4);
        assert_eq!(
            hist.get_data(),
            vec![
                HistogramBucket { index: 0, count: 0 }, // underflow
                HistogramBucket { index: 1, count: 1 },
                HistogramBucket { index: 2, count: 1 },
                HistogramBucket { index: 3, count: 2 },
                HistogramBucket { index: 4, count: 0 } // overflow
            ]
        );

        // Verify `clear` works as expected
        hist.clear();
        assert_eq!(hist.count(), 0);
        assert_eq!(
            hist.get_data(),
            vec![
                HistogramBucket { index: 0, count: 0 }, // underflow
                HistogramBucket { index: 1, count: 0 },
                HistogramBucket { index: 2, count: 0 },
                HistogramBucket { index: 3, count: 0 },
                HistogramBucket { index: 4, count: 0 }, // overflow
            ]
        );
    }

    /// CobaltIntHistogram: tests that invalid data values are logged in the correct
    /// underflow/overflow buckets.
    #[test]
    fn test_cobalt_histogram_invalid_data() {
        let mut hist = CobaltIntHistogram::new(CobaltIntHistogramConfig {
            floor: 0,
            step_size: 1,
            num_buckets: 2,
        });

        hist.add_data(-2);
        hist.add_data(-1);
        hist.add_data(0);
        hist.add_data(1);
        hist.add_data(2);

        assert_eq!(
            hist.get_data(),
            vec![
                HistogramBucket { index: 0, count: 2 }, // underflow
                HistogramBucket { index: 1, count: 1 },
                HistogramBucket { index: 2, count: 1 },
                HistogramBucket { index: 3, count: 1 } // overflow
            ]
        );
    }

    /// Tests that the `get_current_timestamp` function returns the expected current timestamp.
    #[test]
    fn test_get_current_timestamp() {
        use crate::types::Nanoseconds;

        let exec = fuchsia_async::TestExecutor::new_with_fake_time().unwrap();

        exec.set_fake_time(fuchsia_async::Time::from_nanos(0));
        assert_eq!(get_current_timestamp(), Nanoseconds(0));

        exec.set_fake_time(fuchsia_async::Time::from_nanos(1000));
        assert_eq!(get_current_timestamp(), Nanoseconds(1000));
    }
}

#[cfg(test)]
pub mod run_all_tasks_until_stalled {
    /// Runs all tasks known to the current executor until stalled.
    ///
    /// This is a useful convenience function to run `fuchsia_async::Task`s where directly polling
    /// them is either inconvenient or not possible (e.g., detached).
    pub fn run_all_tasks_until_stalled(executor: &mut fuchsia_async::TestExecutor) {
        assert!(executor.run_until_stalled(&mut futures::future::pending::<()>()).is_pending());
    }

    mod tests {
        use super::run_all_tasks_until_stalled;
        use std::cell::Cell;
        use std::rc::Rc;

        #[test]
        fn test_run_all_tasks_until_stalled() {
            let mut executor = fuchsia_async::TestExecutor::new_with_fake_time().unwrap();

            let completed = Rc::new(Cell::new(false));
            let completed_clone = completed.clone();

            let _task = fuchsia_async::Task::local(async move {
                completed_clone.set(true);
            });

            assert_eq!(completed.get(), false);
            run_all_tasks_until_stalled(&mut executor);
            assert_eq!(completed.get(), true);
        }
    }
}
