// Copyright (C) 2026  The Software Heritage developers
// See the AUTHORS file at the top-level directory of this distribution
// License: GNU General Public License version 3, or any later version
// See top-level LICENSE file for more information

use std::sync::atomic::{AtomicU64, Ordering};

use dashmap::DashMap;
use osv::schema::Ecosystem;

use swh_osv::packages::{increment_by_ecosystem, map_package_to_origin_urls};

#[test]
fn test_increment_by_ecosystem() {
    let map: DashMap<String, AtomicU64> = DashMap::new();

    increment_by_ecosystem(&map, &Ecosystem::Npm);
    assert_eq!(map.get("Npm").unwrap().load(Ordering::Relaxed), 1);

    increment_by_ecosystem(&map, &Ecosystem::Npm);
    assert_eq!(map.get("Npm").unwrap().load(Ordering::Relaxed), 2);

    increment_by_ecosystem(&map, &Ecosystem::PyPI);
    assert_eq!(map.get("PyPI").unwrap().load(Ordering::Relaxed), 1);
    assert_eq!(map.get("Npm").unwrap().load(Ordering::Relaxed), 2);
}

#[test]
fn test_map_package_to_origin_urls_simple() {
    let urls = map_package_to_origin_urls(&Ecosystem::Npm, "react");
    assert_eq!(urls, vec!["https://www.npmjs.com/package/react"]);

    let urls = map_package_to_origin_urls(&Ecosystem::PyPI, "django");
    assert_eq!(urls, vec!["https://pypi.org/project/django/"]);

    let urls = map_package_to_origin_urls(&Ecosystem::Go, "github.com/example/repo");
    assert_eq!(urls, vec!["https://pkg.go.dev/github.com/example/repo"]);

    let urls = map_package_to_origin_urls(&Ecosystem::CRAN, "ggplot2");
    assert_eq!(urls, vec!["https://cran.r-project.org/package=ggplot2"]);

    let urls = map_package_to_origin_urls(&Ecosystem::GitHubActions, "actions/checkout");
    assert_eq!(urls, vec!["https://github.com/actions/checkout"]);

    let urls = map_package_to_origin_urls(&Ecosystem::Pub, "flutter_bloc");
    assert_eq!(urls, vec!["https://pub.dev/packages/flutter_bloc"]);
}

#[test]
fn test_map_package_to_origin_urls_ubuntu() {
    let urls = map_package_to_origin_urls(
        &Ecosystem::Ubuntu {
            version: String::from("22.04"),
            pro: false,
            fips: None,
            lts: false,
            metadata: None,
        },
        "curl",
    );
    assert_eq!(
        urls,
        vec![
            "deb://Ubuntu/packages/curl",
            "deb://Ubuntu-Legacy/packages/curl"
        ]
    );
}

#[test]
fn test_map_package_to_origin_urls_ubuntu_pro() {
    let urls = map_package_to_origin_urls(
        &Ecosystem::Ubuntu {
            version: String::from("22.04"),
            pro: true,
            fips: None,
            lts: false,
            metadata: None,
        },
        "curl",
    );
    assert_eq!(urls, Vec::<String>::new());
}

#[test]
fn test_map_package_to_origin_urls_debian() {
    let urls = map_package_to_origin_urls(&Ecosystem::Debian(Some(String::from("12"))), "nginx");
    assert_eq!(
        urls,
        vec![
            "deb://Debian/packages/nginx",
            "deb://Debian-Security/packages/nginx",
            "http://snapshot.debian.org/package/nginx/"
        ]
    );
}

#[test]
fn test_map_package_to_origin_urls_maven() {
    let urls = map_package_to_origin_urls(
        &Ecosystem::Maven(String::new()),
        "org.springframework:spring-core",
    );
    assert_eq!(
        urls,
        vec!["https://repo1.maven.org/maven2/org/springframework/spring-core"]
    );

    let urls = map_package_to_origin_urls(
        &Ecosystem::Maven(String::new()),
        "org.xwiki.platform:xwiki-core",
    );
    assert_eq!(
        urls,
        vec![
            "https://repo1.maven.org/maven2/org/xwiki/platform/xwiki-core",
            "https://maven.xwiki.org/releases/org/xwiki/platform/xwiki-core"
        ]
    );

    let urls = map_package_to_origin_urls(
        &Ecosystem::Maven(String::new()),
        "org.jenkins-ci.plugins:git",
    );
    assert_eq!(
        urls,
        vec![
            "https://repo1.maven.org/maven2/org/jenkins-ci/plugins/git",
            "https://repo.jenkins-ci.org/releases/org/jenkins-ci/plugins/git"
        ]
    );

    let urls =
        map_package_to_origin_urls(&Ecosystem::Maven(String::new()), "org.gradle:gradle-core");
    assert_eq!(
        urls,
        vec![
            "https://repo1.maven.org/maven2/org/gradle/gradle-core",
            "https://repo.gradle.org/ui/native/libs-releases/org/gradle/gradle-core"
        ]
    );

    let urls = map_package_to_origin_urls(
        &Ecosystem::Maven(String::from("https://custom.repo.com/maven2")),
        "com.example:artifact",
    );
    assert_eq!(
        urls,
        vec!["https://custom.repo.com/maven2/com/example/artifact"]
    );

    let urls = map_package_to_origin_urls(&Ecosystem::Maven(String::new()), "invalid-name");
    assert_eq!(urls, Vec::<String>::new());
}

#[test]
fn test_map_package_to_origin_urls_swift_url() {
    let urls = map_package_to_origin_urls(
        &Ecosystem::SwiftURL,
        "https://github.com/apple/swift-package.git",
    );
    assert_eq!(urls, vec!["https://github.com/apple/swift-package.git"]);
}

#[test]
fn test_map_package_to_origin_urls_linux() {
    let urls = map_package_to_origin_urls(&Ecosystem::Linux, "kernel");
    assert_eq!(
        urls,
        vec![
            "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/",
            "https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git"
        ]
    );
}

#[test]
fn test_map_package_to_origin_urls_javascript() {
    let urls = map_package_to_origin_urls(&Ecosystem::JavaScript, "lodash");
    assert_eq!(urls, vec!["https://www.npmjs.com/package/lodash"]);
}

#[test]
fn test_map_package_to_origin_urls_unsupported_ecosystem() {
    let urls = map_package_to_origin_urls(&Ecosystem::CratesIO, "tokio");
    assert_eq!(urls, Vec::<String>::new());

    let urls = map_package_to_origin_urls(&Ecosystem::RubyGems, "rails");
    assert_eq!(urls, Vec::<String>::new());

    let urls = map_package_to_origin_urls(&Ecosystem::NuGet, "Newtonsoft.Json");
    assert_eq!(urls, Vec::<String>::new());
}
