#![allow(missing_docs)]

use std::fs;
use std::path::PathBuf;

use pretty_assertions::assert_str_eq;

use cargo_toml_edit::{
    DependencyFilter,
    Manifest,
    cfg_expr::targets::{Arch, Triple},
};

const NORMALIZE_FILES: [&str; 6] = [
    "bzip2-sys-0.1.11",
    "curl-sys-0.4.66",
    "libgit2-sys-0.16.1",
    "zstd-sys-2.0.8",
    // noop test cases
    "serde-1.0.196",
    "syn-2.0.34",
];

const STRIP_FILES: [&str; 17] = [
    "anstream-0.5.0",
    "backtrace-0.3.69",
    "bytes-1.5.0",
    "chrono-0.4.31",
    "cpufeatures-0.2.9",
    "gst-plugin-gtk4-0.11.0",
    "indicatif-0.17.7",
    "native-tls-0.2.11",
    "nix-0.27.1",
    "rustix-0.36.8",
    "time-0.3.29",
    "tokio-1.32.0",
    "which-4.4.2",
    "wild-2.2.0",
    "zbus-3.14.1",
    // noop test cases
    "serde-1.0.196",
    "syn-2.0.34",
];

fn old_from_prefix(prefix: &str) -> PathBuf {
    let mut path = PathBuf::new();
    path.push(env!("CARGO_MANIFEST_DIR"));
    path.push("tests/data");
    path.push(format!("{prefix}.Cargo.toml"));
    path
}

fn new_from_prefix(prefix: &str) -> PathBuf {
    let mut path = PathBuf::new();
    path.push(env!("CARGO_MANIFEST_DIR"));
    path.push("tests/data");
    path.push(format!("{prefix}.Cargo.toml.patched"));
    path
}


fn default_fedora_filter() -> DependencyFilter {
    // default configuration for Fedora
    const TARGET_TRIPLES: [Triple; 7] = [
        Triple::new_const("x86_64-unknown-linux-gnu"),
        Triple::new_const("i686-unknown-linux-gnu"),
        Triple::new_const("aarch64-unknown-linux-gnu"),
        Triple::new_const("armv7-unknown-linux-gnueabihf"),
        Triple::new_const("powerpc64le-unknown-linux-gnu"),
        Triple::new_const("s390x-unknown-linux-gnu"),
        Triple::new_const("riscv64gc-unknown-linux-gnu"),
    ];

    let mut filter = DependencyFilter::empty();
    filter.target_arch = vec![
        Arch::x86_64,
        Arch::x86,
        Arch::aarch64,
        Arch::arm,
        Arch::powerpc64,
        Arch::s390x,
        Arch::riscv64,
    ];
    filter.target_triple = TARGET_TRIPLES.into();

    filter
}

#[test]
fn normalize_version() {
    for prefix in NORMALIZE_FILES {
        println!("Testing: {}", prefix);

        let original_path = old_from_prefix(prefix);
        let expected_path = new_from_prefix(prefix);

        let original_toml = fs::read_to_string(original_path).unwrap();
        let expected_toml = fs::read_to_string(expected_path).unwrap();

        let mut manifest: Manifest = original_toml.parse().unwrap();
        manifest.normalize_version().unwrap();
        let patched_toml = manifest.to_string();

        assert_str_eq!(
            patched_toml,
            expected_toml,
            "Mismatch with expected string for {}",
            prefix
        );
    }
}

#[test]
fn filter_dependencies() {
    for prefix in STRIP_FILES {
        println!("Testing: {}", prefix);

        let original_path = old_from_prefix(prefix);
        let expected_path = new_from_prefix(prefix);

        let original_toml = fs::read_to_string(original_path).unwrap();
        let expected_toml = fs::read_to_string(expected_path).unwrap();

        let mut manifest: Manifest = original_toml.parse().unwrap();
        manifest.filter_dependencies(&default_fedora_filter()).unwrap();
        let patched_toml = manifest.to_string();

        assert_str_eq!(
            patched_toml,
            expected_toml,
            "Mismatch with expected string for {}",
            prefix
        );
    }
}
