// 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::file_handler,
    anyhow::Error,
    serde_json::{json, Value as JsonValue},
    tracing::*,
};

// Make sure extremely deep-tree data doesn't overflow a stack.
const MAX_TREE_DEPTH: u32 = 128;

fn store_data(inspect_node: &fuchsia_inspect::Node, name: &str, data: &JsonValue, depth: u32) {
    if depth > MAX_TREE_DEPTH {
        return;
    }
    match data {
        JsonValue::String(value) => inspect_node.record_string(name, value),
        JsonValue::Number(value) => {
            if value.is_i64() {
                inspect_node.record_int(name, value.as_i64().unwrap());
            } else if value.is_u64() {
                inspect_node.record_uint(name, value.as_u64().unwrap());
            } else if value.is_f64() {
                inspect_node.record_double(name, value.as_f64().unwrap());
            }
        }
        JsonValue::Bool(value) => inspect_node.record_bool(name, *value),
        JsonValue::Object(object) => inspect_node.record_child(name, |node| {
            for (name, value) in object.iter() {
                store_data(node, name, value, depth + 1);
            }
        }),
        JsonValue::Null => {}
        // TODO(https://fxbug.dev/42150693): If the array is all numbers, publish them (and test).
        JsonValue::Array(_) => {}
    }
}

pub fn serve_persisted_data(persist_root: &fuchsia_inspect::Node) -> Result<(), Error> {
    let remembered_data = file_handler::remembered_data()?;
    for (service_name, service_data) in remembered_data.iter() {
        persist_root.record_child(service_name, |service_node| {
            for (tag_name, tag_data) in service_data.iter() {
                let json_data = serde_json::from_str(tag_data).unwrap_or_else(|err| {
                    error!("Error {:?} parsing stored data", err);
                    json!("<<Error parsing saved data>>")
                });
                store_data(service_node, tag_name, &json_data, 0);
            }
        });
    }
    Ok(())
}

#[cfg(test)]
mod test {
    use super::*;
    use diagnostics_assertions::assert_data_tree;
    use fuchsia_inspect::Inspector;

    // This tests all the types, and also the stack-safety mechanism by including data that should
    // be clipped.
    #[fuchsia::test]
    fn test_json_export() -> Result<(), Error> {
        let inspector = Inspector::default();
        let inspect = inspector.root();
        assert_data_tree!(
            inspector,
            root: contains {
            }
        );

        let data_json = "{ negint: -5, int: 42, unsigned: 0, float: 45.6, \
                         bool: true, obj: { child: 'child', grandchild: { hello: 'world', \
                         great_grand: { should_be_clipped: true } } } }";
        let mut data_parsed = serde_json5::from_str::<serde_json::Value>(data_json)?;
        // serde_json5::from_str() won't parse a number this big, so I have to insert it afterward.
        *data_parsed.get_mut("unsigned").unwrap() = serde_json::json!(9223372036854775808u64);
        store_data(inspect, "types", &data_parsed, MAX_TREE_DEPTH - 3);

        assert_data_tree!(
            inspector,
            root: {
                types: {
                    negint: -5i64,
                    int: 42i64,
                    unsigned: 9223372036854775808u64,
                    float: 45.6f64,
                    bool: true,
                    obj: {
                        child: "child",
                        grandchild: {
                            hello: "world",
                            great_grand: {}
                        }
                    }
                }
            }
        );
        Ok(())
    }
}
