// Copyright 2022 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 {
    bind::compiler::Symbol,
    bind::interpreter::match_bind::{DeviceProperties, PropertyKey},
    fidl_fuchsia_driver_framework as fdf, fidl_fuchsia_driver_index as fdi,
    fuchsia_zircon::{zx_status_t, Status},
    std::collections::HashMap,
};

#[derive(Debug, PartialEq)]
struct DeviceGroupNodePropertyValue {
    is_equal: bool,
    values: Vec<Symbol>,
}

#[derive(Debug, PartialEq)]
pub struct Node {
    name: String,
    properties: HashMap<PropertyKey, DeviceGroupNodePropertyValue>,
}

#[derive(Debug, PartialEq)]
pub struct DeviceGroup {
    topological_path: String,
    nodes: Vec<Node>,
}

impl DeviceGroup {
    pub fn create(
        topological_path: String,
        device_group_nodes: Vec<fdf::DeviceGroupNode>,
    ) -> Result<Self, zx_status_t> {
        Ok(DeviceGroup {
            topological_path: topological_path,
            nodes: device_group_nodes
                .into_iter()
                .map(|node| {
                    Ok(Node {
                        name: node.name,
                        properties: group_node_to_device_property(&node.properties)?,
                    })
                })
                .collect::<Result<Vec<Node>, zx_status_t>>()?,
        })
    }

    // TODO(fxb/103206): Return a list of device groups in a MatchedDeviceGroupNode.
    pub fn matches(&self, properties: &DeviceProperties) -> Option<fdi::MatchedDriver> {
        for (index, node) in self.nodes.iter().enumerate() {
            if match_node(&node, properties) {
                let node_info = fdi::MatchedDeviceGroupInfo {
                    topological_path: Some(self.topological_path.clone()),
                    node_index: Some(index as u32),
                    ..fdi::MatchedDeviceGroupInfo::EMPTY
                };

                return Some(fdi::MatchedDriver::DeviceGroupNode(
                    fdi::MatchedDeviceGroupNodeInfo {
                        device_groups: Some(vec![node_info]),
                        ..fdi::MatchedDeviceGroupNodeInfo::EMPTY
                    },
                ));
            }
        }

        None
    }
}

fn match_node(node: &Node, device_properties: &DeviceProperties) -> bool {
    for (key, prop_values) in node.properties.iter() {
        let match_property = match device_properties.get(key) {
            Some(val) => prop_values.values.contains(val),
            None => {
                // If the node properties contain a false boolean
                // value, then evaluate this to true.
                prop_values.values.contains(&Symbol::BoolValue(false))
            }
        };

        if prop_values.is_equal && !match_property {
            return false;
        }

        if !prop_values.is_equal && match_property {
            return false;
        }
    }
    true
}

fn node_property_to_symbol(value: &fdf::NodePropertyValue) -> Symbol {
    match value {
        fdf::NodePropertyValue::IntValue(i) => {
            bind::compiler::Symbol::NumberValue(i.clone().into())
        }
        fdf::NodePropertyValue::StringValue(s) => bind::compiler::Symbol::StringValue(s.clone()),
        fdf::NodePropertyValue::EnumValue(s) => bind::compiler::Symbol::EnumValue(s.clone()),
        fdf::NodePropertyValue::BoolValue(b) => bind::compiler::Symbol::BoolValue(b.clone()),
    }
}

fn group_node_to_device_property(
    node_properties: &Vec<fdf::DeviceGroupProperty>,
) -> Result<HashMap<PropertyKey, DeviceGroupNodePropertyValue>, zx_status_t> {
    let mut device_properties = HashMap::new();

    for property in node_properties {
        let key = match &property.key {
            fdf::NodePropertyKey::IntValue(i) => PropertyKey::NumberKey(i.clone().into()),
            fdf::NodePropertyKey::StringValue(s) => PropertyKey::StringKey(s.clone()),
        };

        // Contains duplicate keys.
        if device_properties.contains_key(&key) {
            return Err(Status::INVALID_ARGS.into_raw());
        }

        let first_val = property.values.first().ok_or(Status::INVALID_ARGS.into_raw())?;
        let values = property
            .values
            .iter()
            .map(|val| {
                // The properties should all be the same type.
                if std::mem::discriminant(first_val) != std::mem::discriminant(val) {
                    return Err(Status::INVALID_ARGS.into_raw());
                }
                Ok(node_property_to_symbol(val))
            })
            .collect::<Result<Vec<Symbol>, zx_status_t>>()?;

        let is_equal = property.condition == fdf::Condition::Accept;
        device_properties
            .insert(key, DeviceGroupNodePropertyValue { is_equal: is_equal, values: values });
    }
    Ok(device_properties)
}

#[cfg(test)]
mod tests {
    use super::*;
    use bind::compiler::Symbol;
    use bind::interpreter::match_bind::PropertyKey;
    use fuchsia_async as fasync;

    #[fasync::run_singlethreaded(test)]
    async fn test_property_match() {
        let node_properties_1 = vec![
            fdf::DeviceGroupProperty {
                key: fdf::NodePropertyKey::IntValue(1),
                condition: fdf::Condition::Accept,
                values: vec![fdf::NodePropertyValue::IntValue(200)],
            },
            fdf::DeviceGroupProperty {
                key: fdf::NodePropertyKey::IntValue(3),
                condition: fdf::Condition::Accept,
                values: vec![fdf::NodePropertyValue::BoolValue(true)],
            },
            fdf::DeviceGroupProperty {
                key: fdf::NodePropertyKey::StringValue("killdeer".to_string()),
                condition: fdf::Condition::Accept,
                values: vec![fdf::NodePropertyValue::StringValue("plover".to_string())],
            },
        ];

        let node_properties_2 = vec![
            fdf::DeviceGroupProperty {
                key: fdf::NodePropertyKey::StringValue("killdeer".to_string()),
                condition: fdf::Condition::Reject,
                values: vec![fdf::NodePropertyValue::StringValue("plover".to_string())],
            },
            fdf::DeviceGroupProperty {
                key: fdf::NodePropertyKey::StringValue("Moon".to_string()),
                condition: fdf::Condition::Accept,
                values: vec![fdf::NodePropertyValue::EnumValue("Moon.Half".to_string())],
            },
            fdf::DeviceGroupProperty {
                key: fdf::NodePropertyKey::StringValue("yellowlegs".to_string()),
                condition: fdf::Condition::Reject,
                values: vec![fdf::NodePropertyValue::BoolValue(true)],
            },
        ];

        let device_group = DeviceGroup::create(
            "test/path".to_string(),
            vec![
                fdf::DeviceGroupNode {
                    name: "whimbrel".to_string(),
                    properties: node_properties_1.clone(),
                },
                fdf::DeviceGroupNode {
                    name: "godwit".to_string(),
                    properties: node_properties_2.clone(),
                },
            ],
        )
        .unwrap();

        // Match node 1.
        let mut device_properties_1: DeviceProperties = HashMap::new();
        device_properties_1.insert(PropertyKey::NumberKey(1), Symbol::NumberValue(200));
        device_properties_1.insert(
            PropertyKey::StringKey("kingfisher".to_string()),
            Symbol::StringValue("kookaburra".to_string()),
        );
        device_properties_1.insert(PropertyKey::NumberKey(3), Symbol::BoolValue(true));
        device_properties_1.insert(
            PropertyKey::StringKey("killdeer".to_string()),
            Symbol::StringValue("plover".to_string()),
        );

        let expected_device_group = fdi::MatchedDeviceGroupInfo {
            topological_path: Some("test/path".to_string()),
            node_index: Some(0),
            ..fdi::MatchedDeviceGroupInfo::EMPTY
        };
        assert_eq!(
            Some(fdi::MatchedDriver::DeviceGroupNode(fdi::MatchedDeviceGroupNodeInfo {
                device_groups: Some(vec![expected_device_group]),
                ..fdi::MatchedDeviceGroupNodeInfo::EMPTY
            })),
            device_group.matches(&device_properties_1)
        );

        // Match node 2.
        let mut device_properties_2: DeviceProperties = HashMap::new();
        device_properties_2
            .insert(PropertyKey::StringKey("yellowlegs".to_string()), Symbol::BoolValue(false));
        device_properties_2.insert(
            PropertyKey::StringKey("killdeer".to_string()),
            Symbol::StringValue("lapwing".to_string()),
        );
        device_properties_2.insert(
            PropertyKey::StringKey("Moon".to_string()),
            Symbol::EnumValue("Moon.Half".to_string()),
        );

        let expected_device_group_2 = fdi::MatchedDeviceGroupInfo {
            topological_path: Some("test/path".to_string()),
            node_index: Some(1),
            ..fdi::MatchedDeviceGroupInfo::EMPTY
        };
        assert_eq!(
            Some(fdi::MatchedDriver::DeviceGroupNode(fdi::MatchedDeviceGroupNodeInfo {
                device_groups: Some(vec![expected_device_group_2]),
                ..fdi::MatchedDeviceGroupNodeInfo::EMPTY
            })),
            device_group.matches(&device_properties_2)
        );
    }

    #[fasync::run_singlethreaded(test)]
    async fn test_property_mismatch() {
        let node_properties_1 = vec![
            fdf::DeviceGroupProperty {
                key: fdf::NodePropertyKey::IntValue(1),
                condition: fdf::Condition::Accept,
                values: vec![fdf::NodePropertyValue::IntValue(200)],
            },
            fdf::DeviceGroupProperty {
                key: fdf::NodePropertyKey::IntValue(3),
                condition: fdf::Condition::Accept,
                values: vec![fdf::NodePropertyValue::BoolValue(true)],
            },
            fdf::DeviceGroupProperty {
                key: fdf::NodePropertyKey::StringValue("killdeer".to_string()),
                condition: fdf::Condition::Accept,
                values: vec![fdf::NodePropertyValue::StringValue("plover".to_string())],
            },
        ];

        let node_properties_2 = vec![
            fdf::DeviceGroupProperty {
                key: fdf::NodePropertyKey::StringValue("killdeer".to_string()),
                condition: fdf::Condition::Accept,
                values: vec![fdf::NodePropertyValue::StringValue("plover".to_string())],
            },
            fdf::DeviceGroupProperty {
                key: fdf::NodePropertyKey::StringValue("yellowlegs".to_string()),
                condition: fdf::Condition::Reject,
                values: vec![fdf::NodePropertyValue::BoolValue(false)],
            },
        ];

        let device_group = DeviceGroup::create(
            "test/path".to_string(),
            vec![
                fdf::DeviceGroupNode {
                    name: "whimbrel".to_string(),
                    properties: node_properties_1.clone(),
                },
                fdf::DeviceGroupNode {
                    name: "godwit".to_string(),
                    properties: node_properties_2.clone(),
                },
            ],
        )
        .unwrap();

        let mut device_properties: DeviceProperties = HashMap::new();
        device_properties.insert(PropertyKey::NumberKey(1), Symbol::NumberValue(200));
        device_properties.insert(
            PropertyKey::StringKey("kingfisher".to_string()),
            Symbol::StringValue("bee-eater".to_string()),
        );
        device_properties
            .insert(PropertyKey::StringKey("yellowlegs".to_string()), Symbol::BoolValue(false));
        device_properties.insert(
            PropertyKey::StringKey("killdeer".to_string()),
            Symbol::StringValue("plover".to_string()),
        );

        assert_eq!(None, device_group.matches(&device_properties));
    }

    #[fasync::run_singlethreaded(test)]
    async fn test_property_match_list() {
        let node_properties_1 = vec![
            fdf::DeviceGroupProperty {
                key: fdf::NodePropertyKey::IntValue(10),
                condition: fdf::Condition::Reject,
                values: vec![
                    fdf::NodePropertyValue::IntValue(200),
                    fdf::NodePropertyValue::IntValue(150),
                ],
            },
            fdf::DeviceGroupProperty {
                key: fdf::NodePropertyKey::StringValue("plover".to_string()),
                condition: fdf::Condition::Accept,
                values: vec![
                    fdf::NodePropertyValue::StringValue("killdeer".to_string()),
                    fdf::NodePropertyValue::StringValue("lapwing".to_string()),
                ],
            },
        ];

        let node_properties_2 = vec![fdf::DeviceGroupProperty {
            key: fdf::NodePropertyKey::IntValue(11),
            condition: fdf::Condition::Reject,
            values: vec![
                fdf::NodePropertyValue::IntValue(20),
                fdf::NodePropertyValue::IntValue(10),
            ],
        }];

        let device_group = DeviceGroup::create(
            "test/path".to_string(),
            vec![
                fdf::DeviceGroupNode {
                    name: "whimbrel".to_string(),
                    properties: node_properties_1.clone(),
                },
                fdf::DeviceGroupNode {
                    name: "godwit".to_string(),
                    properties: node_properties_2.clone(),
                },
            ],
        )
        .unwrap();

        // Match node 1.
        let mut device_properties_1: DeviceProperties = HashMap::new();
        device_properties_1.insert(PropertyKey::NumberKey(10), Symbol::NumberValue(20));
        device_properties_1.insert(
            PropertyKey::StringKey("plover".to_string()),
            Symbol::StringValue("lapwing".to_string()),
        );

        let expected_device_group = fdi::MatchedDeviceGroupInfo {
            topological_path: Some("test/path".to_string()),
            node_index: Some(0),
            ..fdi::MatchedDeviceGroupInfo::EMPTY
        };
        assert_eq!(
            Some(fdi::MatchedDriver::DeviceGroupNode(fdi::MatchedDeviceGroupNodeInfo {
                device_groups: Some(vec![expected_device_group]),
                ..fdi::MatchedDeviceGroupNodeInfo::EMPTY
            })),
            device_group.matches(&device_properties_1)
        );

        // Match node 2.
        let mut device_properties_2: DeviceProperties = HashMap::new();
        device_properties_2.insert(PropertyKey::NumberKey(5), Symbol::NumberValue(20));

        let expected_device_group_2 = fdi::MatchedDeviceGroupInfo {
            topological_path: Some("test/path".to_string()),
            node_index: Some(1),
            ..fdi::MatchedDeviceGroupInfo::EMPTY
        };
        assert_eq!(
            Some(fdi::MatchedDriver::DeviceGroupNode(fdi::MatchedDeviceGroupNodeInfo {
                device_groups: Some(vec![expected_device_group_2]),
                ..fdi::MatchedDeviceGroupNodeInfo::EMPTY
            })),
            device_group.matches(&device_properties_2)
        );
    }

    #[fasync::run_singlethreaded(test)]
    async fn test_property_mismatch_list() {
        let node_properties_1 = vec![
            fdf::DeviceGroupProperty {
                key: fdf::NodePropertyKey::IntValue(10),
                condition: fdf::Condition::Reject,
                values: vec![
                    fdf::NodePropertyValue::IntValue(200),
                    fdf::NodePropertyValue::IntValue(150),
                ],
            },
            fdf::DeviceGroupProperty {
                key: fdf::NodePropertyKey::StringValue("plover".to_string()),
                condition: fdf::Condition::Accept,
                values: vec![
                    fdf::NodePropertyValue::StringValue("killdeer".to_string()),
                    fdf::NodePropertyValue::StringValue("lapwing".to_string()),
                ],
            },
        ];

        let node_properties_2 = vec![
            fdf::DeviceGroupProperty {
                key: fdf::NodePropertyKey::IntValue(11),
                condition: fdf::Condition::Reject,
                values: vec![
                    fdf::NodePropertyValue::IntValue(20),
                    fdf::NodePropertyValue::IntValue(10),
                ],
            },
            fdf::DeviceGroupProperty {
                key: fdf::NodePropertyKey::IntValue(2),
                condition: fdf::Condition::Accept,
                values: vec![fdf::NodePropertyValue::BoolValue(true)],
            },
        ];

        let device_group = DeviceGroup::create(
            "test/path".to_string(),
            vec![
                fdf::DeviceGroupNode {
                    name: "whimbrel".to_string(),
                    properties: node_properties_1.clone(),
                },
                fdf::DeviceGroupNode {
                    name: "godwit".to_string(),
                    properties: node_properties_2.clone(),
                },
            ],
        )
        .unwrap();

        // Match node 1.
        let mut device_properties_1: DeviceProperties = HashMap::new();
        device_properties_1.insert(PropertyKey::NumberKey(10), Symbol::NumberValue(200));
        device_properties_1.insert(
            PropertyKey::StringKey("plover".to_string()),
            Symbol::StringValue("lapwing".to_string()),
        );
        assert_eq!(None, device_group.matches(&device_properties_1));

        // Match node 2.
        let mut device_properties_2: DeviceProperties = HashMap::new();
        device_properties_2.insert(PropertyKey::NumberKey(11), Symbol::NumberValue(10));
        device_properties_2.insert(PropertyKey::NumberKey(2), Symbol::BoolValue(true));

        assert_eq!(None, device_group.matches(&device_properties_2));
    }

    #[fasync::run_singlethreaded(test)]
    async fn test_property_multiple_value_types() {
        let node_properties_1 = vec![fdf::DeviceGroupProperty {
            key: fdf::NodePropertyKey::IntValue(10),
            condition: fdf::Condition::Reject,
            values: vec![
                fdf::NodePropertyValue::IntValue(200),
                fdf::NodePropertyValue::BoolValue(false),
            ],
        }];

        assert_eq!(
            Err(Status::INVALID_ARGS.into_raw()),
            DeviceGroup::create(
                "test/path".to_string(),
                vec![fdf::DeviceGroupNode {
                    name: "whimbrel".to_string(),
                    properties: node_properties_1.clone(),
                }],
            )
        );
    }

    #[fasync::run_singlethreaded(test)]
    async fn test_property_duplicate_key() {
        let node_properties_1 = vec![
            fdf::DeviceGroupProperty {
                key: fdf::NodePropertyKey::IntValue(10),
                condition: fdf::Condition::Reject,
                values: vec![fdf::NodePropertyValue::IntValue(200)],
            },
            fdf::DeviceGroupProperty {
                key: fdf::NodePropertyKey::IntValue(10),
                condition: fdf::Condition::Accept,
                values: vec![fdf::NodePropertyValue::IntValue(10)],
            },
        ];

        assert_eq!(
            Err(Status::INVALID_ARGS.into_raw()),
            DeviceGroup::create(
                "test/path".to_string(),
                vec![fdf::DeviceGroupNode {
                    name: "whimbrel".to_string(),
                    properties: node_properties_1.clone(),
                },],
            )
        );
    }
}
