use std::env;
use std::ffi::OsString;
use std::path::Path;
use std::process::{self, Command, Stdio};
use std::str;

#[cfg(all(feature = "backtrace", not(feature = "std")))]
compile_error! {
    "`backtrace` feature without `std` feature is not supported"
}

fn main() {
    let mut error_generic_member_access = false;
    if cfg!(feature = "std") {
        println!("cargo:rerun-if-changed=build/probe.rs");

        let consider_rustc_bootstrap;
        if compile_probe(false) {
            // This is a nightly or dev compiler, so it supports unstable
            // features regardless of RUSTC_BOOTSTRAP. No need to rerun build
            // script if RUSTC_BOOTSTRAP is changed.
            error_generic_member_access = true;
            consider_rustc_bootstrap = false;
        } else if let Some(rustc_bootstrap) = env::var_os("RUSTC_BOOTSTRAP") {
            if compile_probe(true) {
                // This is a stable or beta compiler for which the user has set
                // RUSTC_BOOTSTRAP to turn on unstable features. Rerun build
                // script if they change it.
                error_generic_member_access = true;
                consider_rustc_bootstrap = true;
            } else if rustc_bootstrap == "1" {
                // This compiler does not support the generic member access API
                // in the form that anyhow expects. No need to pay attention to
                // RUSTC_BOOTSTRAP.
                error_generic_member_access = false;
                consider_rustc_bootstrap = false;
            } else {
                // This is a stable or beta compiler for which RUSTC_BOOTSTRAP
                // is set to restrict the use of unstable features by this
                // crate.
                error_generic_member_access = false;
                consider_rustc_bootstrap = true;
            }
        } else {
            // Without RUSTC_BOOTSTRAP, this compiler does not support the
            // generic member access API in the form that anyhow expects, but
            // try again if the user turns on unstable features.
            error_generic_member_access = false;
            consider_rustc_bootstrap = true;
        }

        if error_generic_member_access {
            println!("cargo:rustc-cfg=std_backtrace");
            println!("cargo:rustc-cfg=error_generic_member_access");
        }

        if consider_rustc_bootstrap {
            println!("cargo:rerun-if-env-changed=RUSTC_BOOTSTRAP");
        }
    }

    let rustc = match rustc_minor_version() {
        Some(rustc) => rustc,
        None => return,
    };

    if rustc < 51 {
        // core::ptr::addr_of
        // https://blog.rust-lang.org/2021/03/25/Rust-1.51.0.html#stabilized-apis
        println!("cargo:rustc-cfg=anyhow_no_ptr_addr_of");
    }

    if rustc < 52 {
        // core::fmt::Arguments::as_str
        // https://blog.rust-lang.org/2021/05/06/Rust-1.52.0.html#stabilized-apis
        println!("cargo:rustc-cfg=anyhow_no_fmt_arguments_as_str");

        // #![deny(unsafe_op_in_unsafe_fn)]
        // https://github.com/rust-lang/rust/issues/71668
        println!("cargo:rustc-cfg=anyhow_no_unsafe_op_in_unsafe_fn_lint");
    }

    if !error_generic_member_access && cfg!(feature = "std") && rustc >= 65 {
        // std::backtrace::Backtrace
        // https://blog.rust-lang.org/2022/11/03/Rust-1.65.0.html#stabilized-apis
        println!("cargo:rustc-cfg=std_backtrace");
    }
}

fn compile_probe(rustc_bootstrap: bool) -> bool {
    if env::var_os("RUSTC_STAGE").is_some() {
        // We are running inside rustc bootstrap. This is a highly non-standard
        // environment with issues such as:
        //
        //     https://github.com/rust-lang/cargo/issues/11138
        //     https://github.com/rust-lang/rust/issues/114839
        //
        // Let's just not use nightly features here.
        return false;
    }

    let rustc = cargo_env_var("RUSTC");
    let out_dir = cargo_env_var("OUT_DIR");
    let probefile = Path::new("build").join("probe.rs");

    // Make sure to pick up Cargo rustc configuration.
    let mut cmd = if let Some(wrapper) = env::var_os("RUSTC_WRAPPER") {
        let mut cmd = Command::new(wrapper);
        // The wrapper's first argument is supposed to be the path to rustc.
        cmd.arg(rustc);
        cmd
    } else {
        Command::new(rustc)
    };

    if !rustc_bootstrap {
        cmd.env_remove("RUSTC_BOOTSTRAP");
    }

    cmd.stderr(Stdio::null())
        .arg("--edition=2018")
        .arg("--crate-name=anyhow")
        .arg("--crate-type=lib")
        .arg("--emit=dep-info,metadata")
        .arg("--cap-lints=allow")
        .arg("--out-dir")
        .arg(out_dir)
        .arg(probefile);

    if let Some(target) = env::var_os("TARGET") {
        cmd.arg("--target").arg(target);
    }

    // If Cargo wants to set RUSTFLAGS, use that.
    if let Ok(rustflags) = env::var("CARGO_ENCODED_RUSTFLAGS") {
        if !rustflags.is_empty() {
            for arg in rustflags.split('\x1f') {
                cmd.arg(arg);
            }
        }
    }

    match cmd.status() {
        Ok(status) => status.success(),
        Err(_) => false,
    }
}

fn rustc_minor_version() -> Option<u32> {
    let rustc = cargo_env_var("RUSTC");
    let output = Command::new(rustc).arg("--version").output().ok()?;
    let version = str::from_utf8(&output.stdout).ok()?;
    let mut pieces = version.split('.');
    if pieces.next() != Some("rustc 1") {
        return None;
    }
    pieces.next()?.parse().ok()
}

fn cargo_env_var(key: &str) -> OsString {
    env::var_os(key).unwrap_or_else(|| {
        eprintln!(
            "Environment variable ${} is not set during execution of build script",
            key,
        );
        process::exit(1);
    })
}
