// 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::{format_err, Error};
use fidl::endpoints::DiscoverableProtocolMarker;
use fuchsia_component::client::connect_to_protocol;
use fuchsia_zircon::{Status, Vmo};
use once_cell::sync::OnceCell;
use serde_json::Value;
use std::fs::read_dir;
use std::path::{Path, PathBuf};

pub mod macros {
    pub use crate::fx_err_and_bail;
    pub use crate::parse_arg;
    pub use crate::with_line;
}

#[macro_export]
macro_rules! parse_arg {
    ($args:ident, $func:ident, $name:expr) => {
        match $args.get($name) {
            Some(v) => match v.$func() {
                Some(val) => Ok(val),
                None => Err($crate::common_utils::error::Sl4fError::new(
                    format!("malformed {}", $name).as_str(),
                )),
            },
            None => Err($crate::common_utils::error::Sl4fError::new(
                format!("{} missing", $name).as_str(),
            )),
        }
    };
}

#[macro_export]
macro_rules! with_line {
    ($tag:expr) => {
        format!("{}:{}", $tag, line!()).as_str()
    };
}

#[macro_export]
macro_rules! fx_err_and_bail {
    ($tag:expr, $msg:expr) => {{
        tracing::error!(tag = $tag, "{}", $msg);
        return Err(format_err!($msg));
    }};
}

pub fn parse_identifier(args_raw: Value) -> Result<String, Error> {
    let id_raw = match args_raw.get("identifier") {
        Some(id) => id,
        None => return Err(format_err!("Connect peripheral identifier missing")),
    };

    let id = id_raw.as_str().map(String::from);

    match id {
        Some(id) => Ok(id),
        None => return Err(format_err!("Identifier missing")),
    }
}

pub fn parse_identifier_as_u64(args_raw: &Value) -> Result<u64, Error> {
    let id = parse_arg!(args_raw, as_str, "identifier")?;
    id.parse::<u64>().map_err(|_| format_err!("Cannot cast to u64: {}", id))
}

pub fn parse_service_identifier(args_raw: Value) -> Result<u64, Error> {
    parse_arg!(args_raw, as_u64, "service_identifier").map_err(Into::into)
}

pub fn parse_u64_identifier(args_raw: Value) -> Result<u64, Error> {
    parse_arg!(args_raw, as_u64, "identifier").map_err(Into::into)
}

pub fn parse_offset(args_raw: Value) -> Result<u64, Error> {
    parse_arg!(args_raw, as_u64, "offset").map_err(Into::into)
}

pub fn parse_max_bytes(args_raw: Value) -> Result<u64, Error> {
    parse_arg!(args_raw, as_u64, "max_bytes").map_err(Into::into)
}

pub fn parse_psm(args_raw: Value) -> Result<u64, Error> {
    parse_arg!(args_raw, as_u64, "psm").map_err(Into::into)
}

pub fn parse_write_value(args_raw: Value) -> Result<Vec<u8>, Error> {
    let arr = parse_arg!(args_raw, as_array, "write_value")?;
    let mut vector: Vec<u8> = Vec::new();
    for value in arr.into_iter() {
        match value.as_u64() {
            Some(num) => vector.push(num as u8),
            None => {}
        };
    }
    Ok(vector)
}

#[derive(Debug)]
pub struct LazyProxy<P: DiscoverableProtocolMarker>(OnceCell<P::Proxy>);

impl<P: DiscoverableProtocolMarker> Default for LazyProxy<P> {
    fn default() -> Self {
        Self(OnceCell::default())
    }
}

impl<P> LazyProxy<P>
where
    P: DiscoverableProtocolMarker,
    P::Proxy: Clone,
{
    pub fn get_or_connect(&self) -> Result<P::Proxy, Error> {
        let p: &P::Proxy = self.0.get_or_try_init(|| connect_to_protocol::<P>())?;
        Ok(p.clone())
    }

    #[cfg(test)]
    pub fn set(&self, proxy: P::Proxy) -> Result<(), P::Proxy> {
        self.0.set(proxy)
    }
}

pub fn find_file(dir: &Path, pattern: &str) -> Result<PathBuf, Status> {
    for entry in read_dir(dir)? {
        let path = entry?.path();
        if path.ends_with(pattern) {
            return Ok(path);
        }

        if let Ok(res) = find_file(&path, pattern) {
            return Ok(res);
        }
    }
    Err(Status::INTERNAL)
}

/// The offset of the 8-byte size of the JSON data in the VMO.
const JSON_VMO_SIZE_OFFSET: u64 = 0;

/// The offset of the JSON data in the VMO.
const JSON_VMO_DATA_OFFSET: u64 = std::mem::size_of::<u64>() as u64;

/// Write an arbitrary JSON Value into a VMO. The Value can be recovered via read_json_from_vmo().
/// # Arguments
/// * 'vmo' - The VMO into which to write the JSON Value.
/// * 'value' - The JSON Value to write.
pub fn write_json_to_vmo(vmo: &Vmo, value: &Value) -> Result<(), Error> {
    let value_str = serde_json::to_string(value)?;
    let len = value_str.len() as u64;
    let len_bytes = len.to_le_bytes();
    vmo.set_size(JSON_VMO_DATA_OFFSET + len)?;
    vmo.write(&len_bytes, JSON_VMO_SIZE_OFFSET)?;
    vmo.write(value_str.as_bytes(), JSON_VMO_DATA_OFFSET)?;
    Ok(())
}

/// Read an arbitrary JSON Value from a VMO. The Value must previously have been written into the
/// VMO by write_json_to_vmo().
/// # Arguments
/// * 'vmo' - The VMO from which the JSON Value is to be read.
pub fn read_json_from_vmo(vmo: &Vmo) -> Result<Value, Error> {
    let mut len_bytes = [0u8; std::mem::size_of::<u64>()];
    vmo.read(&mut len_bytes, JSON_VMO_SIZE_OFFSET)?;
    let len = u64::from_le_bytes(len_bytes);
    let mut value_bytes = vec![0u8; len as usize];
    vmo.read(&mut value_bytes, JSON_VMO_DATA_OFFSET)?;
    Ok(serde_json::from_str(std::str::from_utf8(&value_bytes)?)?)
}

#[cfg(test)]
mod tests {
    use super::*;
    use fuchsia_zircon::VmoOptions;
    use serde_json::json;

    #[test]
    fn json_to_and_from_vmo() -> Result<(), Error> {
        let expected_value = json!([null, true, 1.5, "string", { "key": "value" }]);
        let vmo = Vmo::create_with_opts(VmoOptions::RESIZABLE, 0)?;
        write_json_to_vmo(&vmo, &expected_value)?;
        let value = read_json_from_vmo(&vmo)?;
        assert_eq!(value, expected_value);
        Ok(())
    }
}
