use lddtree::DependencyAnalyzer;

#[test]
fn test_elf() {
    let analyzer = DependencyAnalyzer::default();
    let deps = analyzer.analyze("tests/test.elf").unwrap();
    assert_eq!(
        deps.interpreter.as_deref(),
        Some("/lib/ld-linux-aarch64.so.1")
    );
    assert_eq!(
        deps.needed,
        &[
            "libz.so.1",
            "libpthread.so.0",
            "libm.so.6",
            "libdl.so.2",
            "libc.so.6",
        ]
    );
    // All directly needed libraries must appear in the dependency map
    for name in &deps.needed {
        assert!(
            deps.libraries.contains_key(name.as_str()),
            "missing library: {name}"
        );
    }
    // The interpreter is keyed by its soname (basename), not its full path.
    // Keying by full path duplicated the dynamic loader on aarch64 glibc
    // hosts, where it is also reachable via DT_NEEDED (issue #19).
    assert!(deps.libraries.contains_key("ld-linux-aarch64.so.1"));
    assert!(!deps.libraries.contains_key("/lib/ld-linux-aarch64.so.1"));
    // 5 direct deps + the interpreter. On aarch64 glibc hosts transitive
    // deps are found on disk, but they resolve to the same 6 names.
    assert_eq!(deps.libraries.len(), 6);
}

#[test]
fn test_macho() {
    let analyzer = DependencyAnalyzer::default();
    let deps = analyzer.analyze("tests/test.macho").unwrap();
    assert!(deps.interpreter.is_none());
    assert_eq!(
        deps.needed,
        &[
            "/usr/lib/libz.1.dylib",
            "/usr/lib/libiconv.2.dylib",
            "/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation",
            "/usr/lib/libSystem.B.dylib"
        ]
    );
    // On macOS, these system libraries exist on disk (in the dyld shared cache),
    // so transitive dependencies will be discovered, making the count >= 4.
    // On other platforms, the install-name paths don't exist, so we get exactly 4
    // not-found entries.
    assert!(deps.libraries.len() >= 4);
}

#[test]
fn test_pe() {
    let analyzer = DependencyAnalyzer::default();
    let deps = analyzer.analyze("tests/test.pe").unwrap();
    assert!(deps.interpreter.is_none());
    assert_eq!(
        deps.needed,
        &[
            "KERNEL32.dll",
            "VCRUNTIME140.dll",
            "api-ms-win-crt-runtime-l1-1-0.dll",
            "api-ms-win-crt-stdio-l1-1-0.dll"
        ]
    );
    // All directly needed libraries must appear in the dependency map
    for name in &deps.needed {
        assert!(
            deps.libraries.contains_key(name.as_str()),
            "missing library: {name}"
        );
    }
    // API set DLLs are virtual — they never exist as real files on disk
    assert!(!deps.libraries["api-ms-win-crt-runtime-l1-1-0.dll"].found());
    assert!(!deps.libraries["api-ms-win-crt-stdio-l1-1-0.dll"].found());
    // On Windows, real system DLLs (e.g., KERNEL32.dll) are found on disk and
    // their transitive dependencies are discovered, so the total library count
    // exceeds the 4 direct deps.  On Linux/macOS no Windows system directories
    // exist, so all non-API-set libs are recorded as not-found and the count
    // stays at 4.
    assert!(deps.libraries.len() >= 4);
}
