use std::env;

fn main() {
    println!("cargo:rerun-if-changed=build.rs");
    let target_arch = env::var("CARGO_CFG_TARGET_ARCH").expect("CARGO_CFG_TARGET_ARCH was not set");
    let target_os = env::var("CARGO_CFG_TARGET_OS").expect("CARGO_CFG_TARGET_OS was not set");
    let target_vendor =
        env::var("CARGO_CFG_TARGET_VENDOR").expect("CARGO_CFG_TARGET_VENDOR was not set");
    let target_env = env::var("CARGO_CFG_TARGET_ENV").expect("CARGO_CFG_TARGET_ENV was not set");

    println!("cargo:rustc-check-cfg=cfg(netbsd10)");
    if target_os == "netbsd" && env::var("RUSTC_STD_NETBSD10").is_ok() {
        println!("cargo:rustc-cfg=netbsd10");
    }

    // Needed for `#![doc(auto_cfg(hide(no_global_oom_handling)))]` attribute.
    println!("cargo::rustc-check-cfg=cfg(no_global_oom_handling)");

    println!("cargo:rustc-check-cfg=cfg(restricted_std)");
    if target_os == "linux"
        || target_os == "android"
        || target_os == "netbsd"
        || target_os == "dragonfly"
        || target_os == "openbsd"
        || target_os == "freebsd"
        || target_os == "solaris"
        || target_os == "illumos"
        || target_os == "macos"
        || target_os == "ios"
        || target_os == "tvos"
        || target_os == "watchos"
        || target_os == "visionos"
        || target_os == "windows"
        || target_os == "fuchsia"
        || (target_vendor == "fortanix" && target_env == "sgx")
        || target_os == "motor"
        || target_os == "hermit"
        || target_os == "trusty"
        || target_os == "l4re"
        || target_os == "redox"
        || target_os == "haiku"
        || target_os == "vxworks"
        || target_arch == "wasm32"
        || target_arch == "wasm64"
        || target_os == "espidf"
        || target_os.starts_with("solid")
        || (target_vendor == "nintendo" && target_env == "newlib")
        || target_os == "vita"
        || target_os == "aix"
        || target_os == "nto"
        || target_os == "qnx"
        || target_os == "xous"
        || target_os == "hurd"
        || target_os == "uefi"
        || target_os == "teeos"
        || target_os == "zkvm"
        || target_os == "rtems"
        || target_os == "nuttx"
        || target_os == "cygwin"
        || target_os == "vexos"

        // See src/bootstrap/src/core/build_steps/synthetic_targets.rs
        || env::var("RUSTC_BOOTSTRAP_SYNTHETIC_TARGET").is_ok()
    {
        // These platforms don't have any special requirements.
    } else {
        // This is for Cargo's build-std support, to mark std as unstable for
        // typically no_std platforms.
        // This covers:
        // - os=none ("bare metal" targets)
        // - mipsel-sony-psp
        // - nvptx64-nvidia-cuda
        // - arch=avr
        // - JSON targets
        // - Any new targets that have not been explicitly added above.
        println!("cargo:rustc-cfg=restricted_std");
    }

    println!("cargo:rustc-check-cfg=cfg(backtrace_in_libstd)");
    println!("cargo:rustc-cfg=backtrace_in_libstd");

    println!("cargo:rustc-env=STD_ENV_ARCH={}", env::var("CARGO_CFG_TARGET_ARCH").unwrap());

    println!("cargo:rustc-check-cfg=cfg(vxworks_lt_25_09)");

    if target_os == "vxworks" {
        match vxworks_version_code() {
            Some((major, minor)) if (major, minor) < (25, 9) => {
                println!("cargo:rustc-cfg=vxworks_lt_25_09");
            }
            _ => {}
        }
    }
}

/// Retrieve the VxWorks release version from the environment variable set by the VxWorks build
/// environment, in `(minor, patch)` form.
fn vxworks_version_code() -> Option<(u32, u32)> {
    let version = env::var("WIND_RELEASE_ID").ok()?;

    let mut pieces = version.trim().split(['.']);

    let major: u32 = pieces.next().and_then(|x| x.parse().ok()).unwrap_or(0);
    let minor: u32 = pieces.next().and_then(|x| x.parse().ok()).unwrap_or(0);

    Some((major, minor))
}
