//! A library for creating new Rust packages with ROS package.xml support.
use ros_new::{args_to_package_xml, env_to_matches};
use std::{collections::HashMap, fs, io::ErrorKind};
use tempfile::tempdir;

#[test]
fn test_args_to_package_xml_success() {
    let temp_dir = tempdir().unwrap();
    let package_path = temp_dir.path().join("test_package");
    fs::create_dir(&package_path).unwrap();

    let mut args = HashMap::new();
    args.insert(
        "package_name".to_string(),
        package_path.to_str().unwrap().to_string(),
    );
    args.insert("format".to_string(), "3".to_string());
    args.insert("description".to_string(), "Test package".to_string());
    args.insert("mail".to_string(), "test@example.com".to_string());
    args.insert("maintainer".to_string(), "Tester".to_string());
    args.insert("license".to_string(), "MIT".to_string());

    let result = args_to_package_xml(&args);
    assert!(result.is_ok());

    let xml_path = package_path.join("package.xml");
    let xml_content = fs::read_to_string(xml_path).unwrap();

    assert!(xml_content.contains("<name>test_package</name>"));
    assert!(xml_content.contains("<description>Test package</description>"));
    assert!(xml_content.contains(r#"<maintainer email="test@example.com">Tester</maintainer>"#));
    assert!(xml_content.contains("<license>MIT</license>"));
}

#[test]
fn test_args_to_package_xml_missing_required_field() {
    let temp_dir = tempdir().unwrap();
    let package_path = temp_dir.path().join("test_package");
    fs::create_dir(&package_path).unwrap();

    let mut args = HashMap::new();
    // Missing package_name
    args.insert("format".to_string(), "3".to_string());
    args.insert("description".to_string(), "Test package".to_string());

    let result = args_to_package_xml(&args);
    assert_eq!(result.unwrap_err(), ErrorKind::NotFound);
}

#[test]
fn test_args_to_package_xml_invalid_path() {
    let mut args = HashMap::new();
    args.insert("package_name".to_string(), "/nonexistent/path".to_string());
    args.insert("format".to_string(), "3".to_string());
    args.insert("description".to_string(), "Test package".to_string());

    let result = args_to_package_xml(&args);
    assert_eq!(result.unwrap_err(), ErrorKind::NotFound);
}

#[test]
fn test_env_to_matches_basic() {
    let args = vec!["program".to_string(), "test_pkg".to_string()];
    let matches = env_to_matches(args);

    assert_eq!(
        matches.get_one::<String>("package_name").unwrap(),
        "test_pkg"
    );
    assert_eq!(matches.get_one::<String>("mail").unwrap(), "you@email.com");
    assert_eq!(matches.get_one::<String>("maintainer").unwrap(), "user");
    assert_eq!(
        matches.get_one::<String>("license").unwrap(),
        "TODO: License declaration"
    );
    assert_eq!(matches.get_one::<String>("format").unwrap(), "3");
}

#[test]
fn test_env_to_matches_with_ros_new_prefix() {
    let args = vec![
        "cargo".to_string(),
        "ros-new".to_string(),
        "test_pkg".to_string(),
    ];
    let matches = env_to_matches(args);

    assert_eq!(
        matches.get_one::<String>("package_name").unwrap(),
        "test_pkg"
    );
}

#[test]
fn test_env_to_matches_with_options() {
    let args = vec![
        "program".to_string(),
        "test_pkg".to_string(),
        "--mail".to_string(),
        "custom@email.com".to_string(),
        "--maintainer".to_string(),
        "custom_user".to_string(),
        "--license".to_string(),
        "Apache-2.0".to_string(),
        "--format".to_string(),
        "2".to_string(),
        "--description".to_string(),
        "Custom description".to_string(),
    ];
    let matches = env_to_matches(args);

    assert_eq!(
        matches.get_one::<String>("mail").unwrap(),
        "custom@email.com"
    );
    assert_eq!(
        matches.get_one::<String>("maintainer").unwrap(),
        "custom_user"
    );
    assert_eq!(matches.get_one::<String>("license").unwrap(), "Apache-2.0");
    assert_eq!(matches.get_one::<String>("format").unwrap(), "2");
    assert_eq!(
        matches.get_one::<String>("description").unwrap(),
        "Custom description"
    );
}

#[test]
fn test_env_to_matches_with_vcs_and_edition() {
    let args = vec![
        "program".to_string(),
        "test_pkg".to_string(),
        "--vcs".to_string(),
        "git".to_string(),
        "--edition".to_string(),
        "2021".to_string(),
    ];
    let matches = env_to_matches(args);

    assert_eq!(matches.get_one::<String>("vcs").unwrap(), "git");
    assert_eq!(matches.get_one::<String>("edition").unwrap(), "2021");
}

#[test]
fn test_env_to_matches_bin_and_lib_flags() {
    let args_bin = vec![
        "program".to_string(),
        "test_pkg".to_string(),
        "--bin".to_string(),
    ];
    let matches_bin = env_to_matches(args_bin);
    assert!(matches_bin.get_flag("bin"));

    let args_lib = vec![
        "program".to_string(),
        "test_pkg".to_string(),
        "--lib".to_string(),
    ];
    let matches_lib = env_to_matches(args_lib);
    assert!(matches_lib.get_flag("lib"));
}
