//! PARSE-H11: Cross-language qname normalization helpers.
//!
//! Each language uses a well-defined separator for qualified names:
//! - Rust: `::`
//! - Python: `.`
//! - JavaScript/TypeScript: `.`
//! - Ruby: `::` (modules/classes) + `.` (method dispatch) — see `lang/ruby/walk.rs`
//! - Go: `.`
//! - Proto: `.`
//! - GraphQL: `.`
//!
//! These helpers centralise the separator policy so hand-rolled
//! `format!("{}::{}", ...)` calls in each extractor can migrate
//! to `qname::join(parts, lang)`.

/// Per-language separator for fully-qualified names.
pub(crate) const fn sep(lang: &str) -> &'static str {
    match lang.as_bytes() {
        b"rust" => "::",
        b"ruby" => "::",  // for module/class nesting; method dispatch uses "."
        b"python" | b"javascript" | b"typescript" | b"go" | b"proto" | b"graphql" => ".",
        _ => ".",
    }
}

/// Join path segments into a qualified name using the language's separator.
///
/// Empty segments are skipped so `join(&["", "Foo", "bar"], "rust")` produces
/// `"Foo::bar"`, not `"::Foo::bar"`.
pub(crate) fn join(parts: &[&str], lang: &str) -> String {
    let sep = sep(lang);
    parts
        .iter()
        .filter(|s| !s.is_empty())
        .copied()
        .collect::<Vec<_>>()
        .join(sep)
}

/// Extract the leaf (last segment) from a qualified name.
/// `"std::collections::HashMap"` → `"HashMap"`.
/// `"os.path.join"` → `"join"`.
pub(crate) fn leaf(qname: &str) -> &str {
    qname
        .rsplit("::")
        .next()
        .and_then(|s| s.rsplit('.').next())
        .unwrap_or(qname)
}

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

    #[test]
    fn rust_separator() {
        assert_eq!(sep("rust"), "::");
        assert_eq!(join(&["std", "collections", "HashMap"], "rust"), "std::collections::HashMap");
    }

    #[test]
    fn python_separator() {
        assert_eq!(sep("python"), ".");
        assert_eq!(join(&["os", "path", "join"], "python"), "os.path.join");
    }

    #[test]
    fn empty_segments_skipped() {
        assert_eq!(join(&["", "Foo", "bar"], "rust"), "Foo::bar");
        assert_eq!(join(&["", ""], "python"), "");
    }

    #[test]
    fn leaf_extraction() {
        assert_eq!(leaf("std::collections::HashMap"), "HashMap");
        assert_eq!(leaf("os.path.join"), "join");
        assert_eq!(leaf("simple"), "simple");
    }
}
