msvc 0.1.0

A tool to automate setup for MSVC projects with vc-ltl and thunk-rs.
use std::process::Command;
use tempfile::TempDir;
use std::fs;

#[test]
#[cfg(target_env = "msvc")]
fn test_cargo_msvc_integration() {
    // Create a temporary directory for our test project
    let temp_dir = TempDir::new().unwrap();
    let project_path = temp_dir.path().join("test_project");

    // Create a new Cargo project in the temporary directory
    let output = Command::new("cargo")
        .args(&["new", "--bin", "test_project"])
        .current_dir(temp_dir.path())
        .output()
        .expect("Failed to create test project");

    assert!(output.status.success(), "Failed to create test project: {}", String::from_utf8_lossy(&output.stderr));

    // Get the path to our cargo-msvc binary
    let cargo_msvc_path = std::env::var("CARGO_BIN_EXE_cargo-msvc")
        .expect("CARGO_BIN_EXE_cargo-msvc not set")
        .to_string();

    // First, add vc-ltl dependency manually (since -t doesn't manage vc-ltl)
    let output = Command::new("cargo")
        .args(&["add", "vc-ltl"])
        .current_dir(&project_path)
        .env("RUSTFLAGS", "-C target-feature=+crt-static")
        .output()
        .expect("Failed to add vc-ltl");
    assert!(output.status.success(), "Failed to add vc-ltl");

    // Now run cargo-msvc -t to add thunk
    let output = Command::new(&cargo_msvc_path)
        .arg("-t")
        .current_dir(&project_path)
        .env("RUSTFLAGS", "-C target-feature=+crt-static")
        .output()
        .expect("Failed to run cargo-msvc");

    // Print stdout and stderr for debugging
    println!("stdout: {}", String::from_utf8_lossy(&output.stdout));
    println!("stderr: {}", String::from_utf8_lossy(&output.stderr));

    // Assert that the command was successful
    assert!(output.status.success(), "cargo-msvc failed");

    // Check that vc-ltl is still present in Cargo.toml (should not be affected by -t)
    let cargo_toml_content = fs::read_to_string(project_path.join("Cargo.toml")).unwrap();
    assert!(cargo_toml_content.contains("vc-ltl"), "vc-ltl should still be present");

    // Check that thunk-rs was added to build dependencies in Cargo.toml
    assert!(cargo_toml_content.contains("thunk-rs"), "thunk-rs not found in Cargo.toml");
    assert!(cargo_toml_content.contains("[build-dependencies]"), "[build-dependencies] section not found in Cargo.toml");

    // Check that build.rs was created
    assert!(project_path.join("build.rs").exists(), "build.rs was not created");

    // Check the content of build.rs
    let build_rs_content = fs::read_to_string(project_path.join("build.rs")).unwrap();
    assert!(build_rs_content.contains("// This file is automatically generated/managed by cargo-msvc."), "Managed marker not found in build.rs");
    assert!(build_rs_content.contains("std::env::var(\"CARGO_CFG_TARGET_ENV\")"), "MSVC environment check not found in build.rs");
    assert!(build_rs_content.contains("thunk::thunk();"), "thunk::thunk() call not found in build.rs");

    // Run cargo-msvc -t again to remove thunk-rs
    let output2 = Command::new(&cargo_msvc_path)
        .arg("-t")
        .current_dir(&project_path)
        .output()
        .expect("Failed to run cargo-msvc");

    // Assert that the command was successful
    assert!(output2.status.success(), "cargo-msvc failed");

    // Check that thunk-rs was removed from Cargo.toml
    let cargo_toml_content2 = fs::read_to_string(project_path.join("Cargo.toml")).unwrap();
    assert!(cargo_toml_content2.contains("vc-ltl"), "vc-ltl should still be present");
    assert!(!cargo_toml_content2.contains("thunk-rs"), "thunk-rs should have been removed from Cargo.toml");

    // Check that build.rs still exists but without thunk call
    assert!(project_path.join("build.rs").exists(), "build.rs should still exist");
    let build_rs_content2 = fs::read_to_string(project_path.join("build.rs")).unwrap();
    assert!(build_rs_content2.contains("// This file is automatically generated/managed by cargo-msvc."), "Managed marker should still be present");
    assert!(!build_rs_content2.contains("thunk::thunk();"), "thunk::thunk() should have been removed");
    assert!(build_rs_content2.contains("fn main()"), "main function should still exist");
}