// 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 {
    crate::core::collection::Zbi,
    anyhow::Result,
    scrutiny::{model::controller::DataController, model::model::*},
    serde::{Deserialize, Serialize},
    serde_json::{json, value::Value},
    std::sync::Arc,
};

#[derive(Default)]
pub struct VerifyBuildController {}

/// Defines the set of security properties that the `VerifyBuildController`
/// checks.
#[derive(Deserialize, Serialize, Debug, Clone, PartialEq, Eq)]
struct SecurityProperties {
    pub zbi: ZbiProperties,
}

/// Defines the subset of security properties related to the ZBI that the
/// `VerifyBuildController` checks.
#[derive(Deserialize, Serialize, Debug, Clone, PartialEq, Eq)]
struct ZbiProperties {
    debug_syscalls_enabled: bool,
}

impl DataController for VerifyBuildController {
    /// Extracts information from the `DataModel` to determine what security
    /// properties are present in a given Fuchsia build. This is intended to
    /// be used by third party tests to inspect the security features
    /// present given build.
    fn query(&self, model: Arc<DataModel>, _value: Value) -> Result<Value> {
        let zbi = model.get::<Zbi>()?;
        Ok(json! {SecurityProperties {
            zbi: ZbiProperties {
                debug_syscalls_enabled: zbi.cmdline.contains("kernel.enable-debugging-syscalls=true"),
            },
        }})
    }

    fn description(&self) -> String {
        "Verifies the existence of security properties in a given build.".to_string()
    }
}

#[cfg(test)]
mod tests {
    use {
        super::*, crate::core::collection::Zbi, scrutiny_utils::zbi::ZbiSection, serde_json::json,
        std::collections::HashMap, tempfile::tempdir,
    };

    fn data_model() -> Arc<DataModel> {
        let store_dir = tempdir().unwrap();
        let uri = store_dir.into_path().into_os_string().into_string().unwrap();
        Arc::new(DataModel::connect(uri).unwrap())
    }

    fn zbi() -> Zbi {
        let bootfs: HashMap<String, Vec<u8>> = HashMap::default();
        let sections: Vec<ZbiSection> = Vec::default();
        return Zbi { sections: sections, bootfs: bootfs, cmdline: "".to_string() };
    }

    #[test]
    fn test_zbi_cmdline_verify_no_debug_syscalls_exists() {
        let model = data_model();
        let zbi = Zbi { cmdline: "{kernel.enable-debugging-syscalls=false}".to_string(), ..zbi() };
        model.set(zbi).unwrap();
        let verify = VerifyBuildController::default();
        let response: SecurityProperties =
            serde_json::from_value(verify.query(model.clone(), json!("{}")).unwrap()).unwrap();
        assert_eq!(response.zbi.debug_syscalls_enabled, false);
    }

    #[test]
    fn test_zbi_cmdline_verify_debug_syscalls_exist() {
        let model = data_model();
        let zbi = Zbi { cmdline: "{kernel.enable-debugging-syscalls=true}".to_string(), ..zbi() };
        model.set(zbi).unwrap();
        let verify = VerifyBuildController::default();
        let response: SecurityProperties =
            serde_json::from_value(verify.query(model.clone(), json!("{}")).unwrap()).unwrap();
        assert_eq!(response.zbi.debug_syscalls_enabled, true);
    }
}
