use std::collections::{BTreeMap, BTreeSet};

use anyhow::{anyhow, Context, Result};
use cfg_expr::targets::{get_builtin_target_by_triple, TargetInfo};
use cfg_expr::{Expression, Predicate};

use crate::context::CrateContext;
use crate::utils::target_triple::TargetTriple;

/// Walk through all dependencies in a [CrateContext] list for all configuration specific
/// dependencies to produce a mapping of configurations/Cargo target_triples to compatible
/// Bazel target_triples.  Also adds mappings for all known target_triples.
pub fn resolve_cfg_platforms(
    crates: Vec<&CrateContext>,
    supported_platform_triples: &BTreeSet<TargetTriple>,
) -> Result<BTreeMap<String, BTreeSet<TargetTriple>>> {
    // Collect all unique configurations from all dependencies into a single set
    let configurations: BTreeSet<String> = crates
        .iter()
        .flat_map(|ctx| {
            let attr = &ctx.common_attrs;
            let mut configurations = BTreeSet::new();

            configurations.extend(attr.deps.configurations());
            configurations.extend(attr.deps_dev.configurations());
            configurations.extend(attr.proc_macro_deps.configurations());
            configurations.extend(attr.proc_macro_deps_dev.configurations());

            // Chain the build dependencies if some are defined
            if let Some(attr) = &ctx.build_script_attrs {
                configurations.extend(attr.deps.configurations());
                configurations.extend(attr.proc_macro_deps.configurations());
            }

            configurations
        })
        .collect();

    // Generate target information for each triple string
    let target_infos = supported_platform_triples
        .iter()
        .map(
            |target_triple| match get_builtin_target_by_triple(&target_triple.to_cargo()) {
                Some(info) => Ok((target_triple, info)),
                None => Err(anyhow!(
                    "Invalid platform triple in supported platforms: {}",
                    target_triple
                )),
            },
        )
        .collect::<Result<BTreeMap<&TargetTriple, &'static TargetInfo>>>()?;

    // `cfg-expr` does not understand configurations that are simply platform triples
    // (`x86_64-unknown-linux-gnu` vs `cfg(target = "x86_64-unkonwn-linux-gnu")`). So
    // in order to parse configurations, the text is renamed for the check but the
    // original is retained for comaptibility with the manifest.
    let rename = |cfg: &str| -> String { format!("cfg(target = \"{cfg}\")") };
    let original_cfgs: BTreeMap<String, String> = configurations
        .iter()
        .filter(|cfg| !cfg.starts_with("cfg("))
        .map(|cfg| (rename(cfg), cfg.clone()))
        .collect();

    let mut conditions = configurations
        .into_iter()
        // `cfg-expr` requires that the expressions be actual `cfg` expressions. Any time
        // there's a target triple (which is a valid constraint), convert it to a cfg expression.
        .map(|cfg| match cfg.starts_with("cfg(") {
            true => cfg,
            false => rename(&cfg),
        })
        // Check the current configuration with against each supported triple
        .map(|cfg| {
            let expression =
                Expression::parse(&cfg).context(format!("Failed to parse expression: '{cfg}'"))?;

            let triples = target_infos
                .iter()
                .filter(|(_, target_info)| {
                    expression.eval(|p| match p {
                        Predicate::Target(tp) => tp.matches(**target_info),
                        Predicate::KeyValue { key, val } => {
                            *key == "target" && val == &target_info.triple.as_str()
                        }
                        // For now there is no other kind of matching
                        _ => false,
                    })
                })
                .map(|(triple, _)| (*triple).clone())
                .collect();

            // Map any renamed configurations back to their original IDs
            let cfg = match original_cfgs.get(&cfg) {
                Some(orig) => orig.clone(),
                None => cfg,
            };

            Ok((cfg, triples))
        })
        .collect::<Result<BTreeMap<String, BTreeSet<TargetTriple>>>>()?;
    // Insert identity relationships.
    for target_triple in supported_platform_triples.iter() {
        conditions
            .entry(target_triple.to_bazel())
            .or_default()
            .insert(target_triple.clone());
    }
    Ok(conditions)
}

#[cfg(test)]
mod test {
    use crate::config::CrateId;
    use crate::context::crate_context::CrateDependency;
    use crate::context::CommonAttributes;
    use crate::select::Select;

    use super::*;

    fn supported_platform_triples() -> BTreeSet<TargetTriple> {
        BTreeSet::from([
            TargetTriple::from_bazel("aarch64-apple-darwin".to_owned()),
            TargetTriple::from_bazel("i686-apple-darwin".to_owned()),
            TargetTriple::from_bazel("x86_64-unknown-linux-gnu".to_owned()),
        ])
    }

    #[test]
    fn resolve_no_targeted() {
        let mut deps: Select<BTreeSet<CrateDependency>> = Select::default();
        deps.insert(
            CrateDependency {
                id: CrateId::new("mock_crate_b".to_owned(), "0.1.0".to_owned()),
                target: "mock_crate_b".to_owned(),
                alias: None,
            },
            None,
        );

        let context = CrateContext {
            name: "mock_crate_a".to_owned(),
            version: "0.1.0".to_owned(),
            common_attrs: CommonAttributes {
                deps,
                ..CommonAttributes::default()
            },
            ..CrateContext::default()
        };

        let configurations =
            resolve_cfg_platforms(vec![&context], &supported_platform_triples()).unwrap();

        assert_eq!(
            configurations,
            BTreeMap::from([
                // All known triples.
                (
                    "aarch64-apple-darwin".to_owned(),
                    BTreeSet::from([TargetTriple::from_bazel("aarch64-apple-darwin".to_owned())]),
                ),
                (
                    "i686-apple-darwin".to_owned(),
                    BTreeSet::from([TargetTriple::from_bazel("i686-apple-darwin".to_owned())]),
                ),
                (
                    "x86_64-unknown-linux-gnu".to_owned(),
                    BTreeSet::from([TargetTriple::from_bazel(
                        "x86_64-unknown-linux-gnu".to_owned()
                    )]),
                ),
            ])
        )
    }

    fn mock_resolve_context(configuration: String) -> CrateContext {
        let mut deps: Select<BTreeSet<CrateDependency>> = Select::default();
        deps.insert(
            CrateDependency {
                id: CrateId::new("mock_crate_b".to_owned(), "0.1.0".to_owned()),
                target: "mock_crate_b".to_owned(),
                alias: None,
            },
            Some(configuration),
        );

        CrateContext {
            name: "mock_crate_a".to_owned(),
            version: "0.1.0".to_owned(),
            common_attrs: CommonAttributes {
                deps,
                ..CommonAttributes::default()
            },
            ..CrateContext::default()
        }
    }

    #[test]
    fn resolve_targeted() {
        let data = BTreeMap::from([
            (
                r#"cfg(target = "x86_64-unknown-linux-gnu")"#.to_owned(),
                BTreeSet::from([TargetTriple::from_bazel(
                    "x86_64-unknown-linux-gnu".to_owned(),
                )]),
            ),
            (
                r#"cfg(any(target_os = "macos", target_os = "ios"))"#.to_owned(),
                BTreeSet::from([
                    TargetTriple::from_bazel("aarch64-apple-darwin".to_owned()),
                    TargetTriple::from_bazel("i686-apple-darwin".to_owned()),
                ]),
            ),
        ]);

        data.into_iter().for_each(|(configuration, expectation)| {
            let context = mock_resolve_context(configuration.clone());

            let configurations =
                resolve_cfg_platforms(vec![&context], &supported_platform_triples()).unwrap();

            assert_eq!(
                configurations,
                BTreeMap::from([
                    (configuration, expectation,),
                    // All known triples.
                    (
                        "aarch64-apple-darwin".to_owned(),
                        BTreeSet::from([TargetTriple::from_bazel(
                            "aarch64-apple-darwin".to_owned()
                        )]),
                    ),
                    (
                        "i686-apple-darwin".to_owned(),
                        BTreeSet::from([TargetTriple::from_bazel("i686-apple-darwin".to_owned())]),
                    ),
                    (
                        "x86_64-unknown-linux-gnu".to_owned(),
                        BTreeSet::from([TargetTriple::from_bazel(
                            "x86_64-unknown-linux-gnu".to_owned()
                        )]),
                    ),
                ])
            );
        })
    }

    #[test]
    fn resolve_platforms() {
        let configuration = r#"x86_64-unknown-linux-gnu"#.to_owned();
        let mut deps: Select<BTreeSet<CrateDependency>> = Select::default();
        deps.insert(
            CrateDependency {
                id: CrateId::new("mock_crate_b".to_owned(), "0.1.0".to_owned()),
                target: "mock_crate_b".to_owned(),
                alias: None,
            },
            Some(configuration.clone()),
        );

        let context = CrateContext {
            name: "mock_crate_a".to_owned(),
            version: "0.1.0".to_owned(),
            common_attrs: CommonAttributes {
                deps,
                ..CommonAttributes::default()
            },
            ..CrateContext::default()
        };

        let configurations =
            resolve_cfg_platforms(vec![&context], &supported_platform_triples()).unwrap();

        assert_eq!(
            configurations,
            BTreeMap::from([
                (
                    configuration,
                    BTreeSet::from([TargetTriple::from_bazel(
                        "x86_64-unknown-linux-gnu".to_owned()
                    )])
                ),
                // All known triples.
                (
                    "aarch64-apple-darwin".to_owned(),
                    BTreeSet::from([TargetTriple::from_bazel("aarch64-apple-darwin".to_owned())]),
                ),
                (
                    "i686-apple-darwin".to_owned(),
                    BTreeSet::from([TargetTriple::from_bazel("i686-apple-darwin".to_owned())]),
                ),
                (
                    "x86_64-unknown-linux-gnu".to_owned(),
                    BTreeSet::from([TargetTriple::from_bazel(
                        "x86_64-unknown-linux-gnu".to_owned()
                    )]),
                ),
            ])
        );
    }

    #[test]
    fn resolve_unsupported_targeted() {
        let configuration = r#"cfg(target = "x86_64-unknown-unknown")"#.to_owned();
        let mut deps: Select<BTreeSet<CrateDependency>> = Select::default();
        deps.insert(
            CrateDependency {
                id: CrateId::new("mock_crate_b".to_owned(), "0.1.0".to_owned()),
                target: "mock_crate_b".to_owned(),
                alias: None,
            },
            Some(configuration.clone()),
        );

        let context = CrateContext {
            name: "mock_crate_a".to_owned(),
            version: "0.1.0".to_owned(),
            common_attrs: CommonAttributes {
                deps,
                ..CommonAttributes::default()
            },
            ..CrateContext::default()
        };

        let configurations =
            resolve_cfg_platforms(vec![&context], &supported_platform_triples()).unwrap();

        assert_eq!(
            configurations,
            BTreeMap::from([
                (configuration, BTreeSet::new()),
                // All known triples.
                (
                    "aarch64-apple-darwin".to_owned(),
                    BTreeSet::from([TargetTriple::from_bazel("aarch64-apple-darwin".to_owned())]),
                ),
                (
                    "i686-apple-darwin".to_owned(),
                    BTreeSet::from([TargetTriple::from_bazel("i686-apple-darwin".to_owned())]),
                ),
                (
                    "x86_64-unknown-linux-gnu".to_owned(),
                    BTreeSet::from([TargetTriple::from_bazel(
                        "x86_64-unknown-linux-gnu".to_owned()
                    )]),
                ),
            ])
        );
    }
}
