// Part of the Crubit project, under the Apache License v2.0 with LLVM
// Exceptions. See /LICENSE for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

use import_internal::{AbsoluteLabel, Mode};
use proc_macro2::{Span, TokenStream};
use quote::{quote, ToTokens, TokenStreamExt};
use serde::Deserialize;
use std::collections::BTreeMap;
use std::collections::BTreeSet;
use std::rc::Rc;
use syn::Ident;

/// Representation of a target's namespace hierarchy, as encoded in the
/// *_namespace.json file.
#[derive(Clone, Debug, Deserialize)]
pub struct JsonNamespaceHierarchy {
    pub label: Rc<str>,
    #[serde(default)]
    pub namespaces: Vec<JsonNamespace>,
}

/// Single C++ namespace, as encoded in the *_namespace.json file.
#[derive(Clone, Debug, Deserialize)]
pub struct JsonNamespace {
    pub name: Rc<str>,
    #[serde(default)]
    pub children: Vec<JsonNamespace>,
}

/// A trie-like data structure that represents the merged namespace hierarchy
/// from all the direct dependencies.
#[derive(Clone, Debug)]
pub struct MergedNamespaceHierarchy {
    /// A map of a top level namespace name to the corresponding
    /// MergedNamespace.
    pub top_level_namespaces: BTreeMap<Rc<str>, MergedNamespace>,
}

/// A single C++ namespace potentially reopened across multiple targets.
#[derive(Clone, Debug)]
pub struct MergedNamespace {
    /// name of the current namespace.
    pub name: Rc<str>,
    /// A map of child namespace name to the corresponding MergedNamespace.
    pub children: BTreeMap<Rc<str>, MergedNamespace>,
    /// A set of targets that reopen this namespace.
    pub labels: BTreeSet<Rc<str>>,
}

impl MergedNamespace {
    /// Creates a MergedNamespace from JsonNamespace.
    pub fn from_json_namespace(label: Rc<str>, json_namespace: &JsonNamespace) -> MergedNamespace {
        let mut merged_children = BTreeMap::new();
        for child in json_namespace.children.iter() {
            merged_children.insert(
                child.name.clone(),
                MergedNamespace::from_json_namespace(label.clone(), child),
            );
        }
        MergedNamespace {
            name: json_namespace.name.clone(),
            children: merged_children,
            labels: BTreeSet::from([label]),
        }
    }

    /// Merges the namespace passed as an argument into the current one.
    pub(crate) fn merge(&mut self, other: MergedNamespace) {
        let MergedNamespace { name, children, mut labels } = other;
        assert!(
            self.name == name,
            "Cannot merge namespaces with different names, got '{}' and '{}'",
            &self.name,
            &name
        );
        self.labels.append(&mut labels);
        for namespace in children.into_values() {
            self.add_child(namespace);
        }
    }

    fn add_child(&mut self, namespace: MergedNamespace) {
        self.labels.append(&mut namespace.labels.iter().cloned().collect());
        match self.children.get_mut(&namespace.name) {
            Some(child_namespace) => {
                let MergedNamespace { name: _, children, labels: _ } = namespace;
                for child in children.into_values() {
                    child_namespace.add_child(child);
                }
            }
            None => {
                self.children.insert(namespace.name.clone(), namespace);
            }
        }
    }
}

impl MergedNamespaceHierarchy {
    /// Creates a MergedNamespaceHierarchy from JsonNamespaceHierarchy.
    pub fn from_json_namespace_hierarchy(jnh: &JsonNamespaceHierarchy) -> MergedNamespaceHierarchy {
        let mut merged_namespaces = BTreeMap::new();
        for top_level_namespace in jnh.namespaces.iter() {
            merged_namespaces.insert(
                top_level_namespace.name.clone(),
                MergedNamespace::from_json_namespace(jnh.label.clone(), top_level_namespace),
            );
        }
        MergedNamespaceHierarchy { top_level_namespaces: merged_namespaces }
    }

    // Merges the namespace hierarchy passed as an argument into the current one.
    pub fn merge(&mut self, other: MergedNamespaceHierarchy) {
        for (name, namespace) in other.top_level_namespaces {
            match self.top_level_namespaces.get_mut(&name) {
                Some(child_namespace) => {
                    child_namespace.merge(namespace);
                }
                None => {
                    self.top_level_namespaces.insert(name, namespace);
                }
            }
        }
    }
}

impl ToTokens for MergedNamespaceHierarchy {
    fn to_tokens(&self, tokens: &mut TokenStream) {
        for namespace in self.top_level_namespaces.values() {
            to_use_stmts(namespace, tokens, &mut vec![]);
        }
    }
}

fn to_use_stmts(
    namespace: &MergedNamespace,
    tokens: &mut TokenStream,
    outer_namespaces: &mut Vec<Ident>,
) {
    let module_name = Ident::new(&namespace.name, Span::call_site());

    let mut inner_tokens = TokenStream::new();
    for label_literal in namespace.labels.iter() {
        let span = Span::call_site();
        let label = AbsoluteLabel::parse(label_literal, &span).expect("Couldn't parse label");
        // TODO(rosica): Use mangled name for the crate.
        let crate_name = &label.crate_name(&Mode::NoRenaming);
        let crate_ident = Ident::new(crate_name, span);
        inner_tokens.append_all(quote! {
            pub use #crate_ident::#(#outer_namespaces::)*#module_name::*;
        });
    }
    outer_namespaces.push(module_name);
    for inner in namespace.children.values() {
        to_use_stmts(inner, &mut inner_tokens, outer_namespaces);
    }
    let module_name = outer_namespaces.pop();

    tokens.extend(quote! {
        pub mod #module_name {
            #inner_tokens
        }
    });
}

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

    #[test]
    fn from_json() {
        let json = r#"{
            "label": "//foo/bar:baz",
            "namespaces": [
                {
                    "name": "top_level",
                    "children": []
                }
            ]
        }"#;

        let ns: JsonNamespaceHierarchy = serde_json::from_str(json).unwrap();
        assert_eq!(&*ns.label, "//foo/bar:baz");
        assert_eq!(ns.namespaces.len(), 1);
        assert_eq!(&*ns.namespaces[0].name, "top_level");
    }

    #[test]
    fn test_merge_namespace_hierarchies() {
        let hierarchy_one: JsonNamespaceHierarchy = serde_json::from_str(
            r#"{
            "label": "//foo/bar:baz",
            "namespaces": [
                {
                    "name": "top_level_1",
                    "children": []
                }
            ]
        }"#,
        )
        .unwrap();

        let hierarchy_two: JsonNamespaceHierarchy = serde_json::from_str(
            r#"{
            "label": "//foo/bar:xyz",
            "namespaces": [
                {
                    "name": "top_level_1",
                    "children": []
                },
                {
                    "name": "top_level_2",
                    "children": []
                }
            ]
        }"#,
        )
        .unwrap();

        let mut merged_hierarchy =
            MergedNamespaceHierarchy::from_json_namespace_hierarchy(&hierarchy_one);
        let merged_hierarchy_two =
            MergedNamespaceHierarchy::from_json_namespace_hierarchy(&hierarchy_two);

        merged_hierarchy.merge(merged_hierarchy_two);
        let MergedNamespaceHierarchy { top_level_namespaces } = merged_hierarchy;

        assert_eq!(top_level_namespaces.len(), 2);

        let MergedNamespace { name, children: _, labels } =
            top_level_namespaces.get("top_level_1").unwrap();

        assert_eq!(&**name, "top_level_1");
        assert_eq!(
            labels.iter().map(Deref::deref).collect::<Vec<_>>(),
            ["//foo/bar:baz", "//foo/bar:xyz"]
        );

        let MergedNamespace { name, children: _, labels } =
            top_level_namespaces.get("top_level_2").unwrap();

        assert_eq!(&**name, "top_level_2");
        assert_eq!(labels.iter().map(Deref::deref).collect::<Vec<_>>(), ["//foo/bar:xyz"]);
    }

    #[test]
    #[should_panic(expected = "Cannot merge namespaces with different names, got 'a' and 'b'")]
    fn test_merge_different_namespaces() {
        let mut namespace_one = MergedNamespace::from_json_namespace(
            "//label1".into(),
            &serde_json::from_str(
                r#"{
            "name": "a",
            "children": []
        }"#,
            )
            .unwrap(),
        );

        let namespace_two = MergedNamespace::from_json_namespace(
            "//label2".into(),
            &serde_json::from_str(
                r#"{
            "name": "b",
            "children": []
        }"#,
            )
            .unwrap(),
        );

        namespace_one.merge(namespace_two);
    }

    #[test]
    fn test_merge_namespaces() {
        let json_namespace_one: JsonNamespace = serde_json::from_str(
            r#"{
            "name": "a",
            "children": [
                {
                    "name": "b",
                    "children": []
                },
                {
                    "name": "c",
                    "children": []
                }
            ]
        }"#,
        )
        .unwrap();

        let json_namespace_two: JsonNamespace = serde_json::from_str(
            r#"{
            "name": "a",
            "children": [
                {
                    "name": "c",
                    "children": [
                        {
                            "name": "d",
                            "children": []
                        }
                    ]
                },
                {
                    "name": "d",
                    "children": []
                }
            ]
        }"#,
        )
        .unwrap();

        let mut merged_namespace =
            MergedNamespace::from_json_namespace("//:label1".into(), &json_namespace_one);
        let merged_namespace_two =
            MergedNamespace::from_json_namespace("//:label2".into(), &json_namespace_two);

        merged_namespace.merge(merged_namespace_two);
        let MergedNamespace { name, children, labels } = merged_namespace;

        assert_eq!(&*name, "a");
        assert_eq!(labels.iter().map(Deref::deref).collect::<Vec<_>>(), ["//:label1", "//:label2"]);
        assert_eq!(children.keys().map(Deref::deref).collect::<Vec<_>>(), ["b", "c", "d"]);

        let MergedNamespace { name: _, children: _, labels: b_labels } = children.get("b").unwrap();
        // Namespace b only exists in the first target
        assert_eq!(b_labels.iter().map(Deref::deref).collect::<Vec<_>>(), ["//:label1"]);

        let MergedNamespace { name: _, children: children_c, labels: c_labels } =
            children.get("c").unwrap();
        // Namespace c exists in both targets, however its child d only exists in the
        // second target
        assert_eq!(
            c_labels.iter().map(Deref::deref).collect::<Vec<_>>(),
            ["//:label1", "//:label2"]
        );
        let MergedNamespace { name: _, children: _, labels: c_child_labels } =
            children_c.get("d").unwrap();
        assert_eq!(c_child_labels.iter().map(Deref::deref).collect::<Vec<_>>(), ["//:label2"]);

        let MergedNamespace { name: _, children: _, labels: d_labels } = children.get("d").unwrap();
        // Namespace d only exists in the second target
        assert_eq!(d_labels.iter().map(Deref::deref).collect::<Vec<_>>(), ["//:label2"]);
    }

    #[test]
    fn test_to_tokens() {
        let hierarchy_one: JsonNamespaceHierarchy = serde_json::from_str(
            r#"{
            "label": "//foo/bar:baz",
            "namespaces": [
                {
                    "name": "top_level_1",
                    "children": [
                        {
                            "name": "reopened",
                            "children": [
                                {
                                    "name": "baz_specific",
                                    "children": []
                                }
                            ]
                        }
                    ]
                }
            ]
        }"#,
        )
        .unwrap();

        let hierarchy_two: JsonNamespaceHierarchy = serde_json::from_str(
            r#"{
            "label": "//foo/bar:xyz",
            "namespaces": [
                {
                    "name": "top_level_1",
                    "children": [
                        {
                            "name": "xyz_specific",
                            "children": []
                        },
                        {
                            "name": "reopened",
                            "children": []
                        }
                    ]
                },
                {
                    "name": "top_level_2",
                    "children": []
                }
            ]
        }"#,
        )
        .unwrap();

        let mut merged_hierarchy =
            MergedNamespaceHierarchy::from_json_namespace_hierarchy(&hierarchy_one);
        let merged_hierarchy_two =
            MergedNamespaceHierarchy::from_json_namespace_hierarchy(&hierarchy_two);

        merged_hierarchy.merge(merged_hierarchy_two);

        token_stream_matchers::assert_rs_matches!(
            quote! {#merged_hierarchy},
            quote! {
                pub mod top_level_1 {
                    pub use baz::top_level_1::*;
                    pub use xyz::top_level_1::*;
                    pub mod reopened {
                        pub use baz::top_level_1::reopened::*;
                        pub mod baz_specific {
                            pub use baz::top_level_1::reopened::baz_specific::*;
                        }
                    }
                    pub mod xyz_specific {
                        pub use xyz::top_level_1::xyz_specific::*;
                    }
                }
                pub mod top_level_2 {
                    pub use xyz::top_level_2::*;
                }

            }
        );
    }
}
