// Configuration shared with both libm and libm-test

use std::path::PathBuf;
use std::process::{Command, Stdio};
use std::{env, str};

#[allow(dead_code)]
pub struct Config {
    pub manifest_dir: PathBuf,
    pub out_dir: PathBuf,
    pub opt_level: String,
    pub cargo_features: Vec<String>,
    pub target_triple: String,
    pub target_arch: String,
    pub target_env: String,
    pub target_family: Option<String>,
    pub target_os: String,
    pub target_string: String,
    pub target_vendor: String,
    pub target_features: Vec<String>,
    pub reliable_f128: bool,
    pub reliable_f16: bool,
}

impl Config {
    pub fn from_env() -> Self {
        let target_triple = env::var("TARGET").unwrap();
        let target_features = env::var("CARGO_CFG_TARGET_FEATURE")
            .map(|feats| feats.split(',').map(ToOwned::to_owned).collect())
            .unwrap_or_default();
        let cargo_features = env::vars()
            .filter_map(|(name, _value)| name.strip_prefix("CARGO_FEATURE_").map(ToOwned::to_owned))
            .map(|s| s.to_lowercase().replace("_", "-"))
            .collect();

        // Query rustc for options that Cargo does not provide env for. The bootstrap hack is used
        // to get consistent output regardless of channel (`f16`/`f128` config options are hidden
        // on stable otherwise).
        let mut cmd = Command::new(env::var("RUSTC").unwrap());
        cmd.args(["--print=cfg", "--target", &target_triple])
            .env("RUSTC_BOOTSTRAP", "1")
            .stderr(Stdio::inherit());
        let out = cmd
            .output()
            .unwrap_or_else(|e| panic!("failed to run `{cmd:?}`: {e}"));
        let rustc_cfg = str::from_utf8(&out.stdout).unwrap();

        // If we couldn't query `rustc` (e.g. a custom JSON target was used), make the safe
        // choice and leave `f16` and `f128` disabled.
        let rustc_output_ok = out.status.success();
        let reliable_f128 =
            rustc_output_ok && rustc_cfg.lines().any(|l| l == "target_has_reliable_f128");
        let reliable_f16 =
            rustc_output_ok && rustc_cfg.lines().any(|l| l == "target_has_reliable_f16");

        Self {
            target_triple,
            manifest_dir: PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap()),
            out_dir: PathBuf::from(env::var("OUT_DIR").unwrap()),
            opt_level: env::var("OPT_LEVEL").unwrap(),
            cargo_features,
            target_arch: env::var("CARGO_CFG_TARGET_ARCH").unwrap(),
            target_env: env::var("CARGO_CFG_TARGET_ENV").unwrap(),
            target_family: env::var("CARGO_CFG_TARGET_FAMILY").ok(),
            target_os: env::var("CARGO_CFG_TARGET_OS").unwrap(),
            target_string: env::var("TARGET").unwrap(),
            target_vendor: env::var("CARGO_CFG_TARGET_VENDOR").unwrap(),
            target_features,
            reliable_f128,
            reliable_f16,
        }
    }
}

/// Libm gets most config options made available.
#[allow(dead_code)]
pub fn emit_libm_config(cfg: &Config) {
    emit_intrinsics_cfg();
    emit_arch_cfg();
    emit_optimization_cfg(cfg);
    emit_cfg_shorthands(cfg);
    emit_cfg_env(cfg);
    emit_f16_f128_cfg(cfg);
}

/// Tests don't need most feature-related config.
#[allow(dead_code)]
pub fn emit_test_config(cfg: &Config) {
    emit_optimization_cfg(cfg);
    emit_cfg_shorthands(cfg);
    emit_cfg_env(cfg);
    emit_f16_f128_cfg(cfg);
}

/// Simplify the feature logic for enabling intrinsics so code only needs to use
/// `cfg(intrinsics_enabled)`.
fn emit_intrinsics_cfg() {
    println!("cargo:rustc-check-cfg=cfg(intrinsics_enabled)");

    // Disabled by default; `unstable-intrinsics` enables again; `force-soft-floats` overrides
    // to disable.
    if cfg!(feature = "unstable-intrinsics") && !cfg!(feature = "force-soft-floats") {
        println!("cargo:rustc-cfg=intrinsics_enabled");
    }
}

/// Simplify the feature logic for enabling arch-specific features so code only needs to use
/// `cfg(arch_enabled)`.
fn emit_arch_cfg() {
    println!("cargo:rustc-check-cfg=cfg(arch_enabled)");

    // Enabled by default via the "arch" feature, `force-soft-floats` overrides to disable.
    if cfg!(feature = "arch") && !cfg!(feature = "force-soft-floats") {
        println!("cargo:rustc-cfg=arch_enabled");
    }
}

/// Some tests are extremely slow. Emit a config option based on optimization level.
fn emit_optimization_cfg(cfg: &Config) {
    println!("cargo:rustc-check-cfg=cfg(optimizations_enabled)");

    if !matches!(cfg.opt_level.as_str(), "0" | "1") {
        println!("cargo:rustc-cfg=optimizations_enabled");
    }
}

/// Provide an alias for common longer config combinations.
fn emit_cfg_shorthands(cfg: &Config) {
    println!("cargo:rustc-check-cfg=cfg(x86_no_sse)");
    if cfg.target_arch == "x86" && !cfg.target_features.iter().any(|f| f == "sse") {
        // Shorthand to detect i586 targets
        println!("cargo:rustc-cfg=x86_no_sse");
    }
}

/// Reemit config that we make use of for test logging.
fn emit_cfg_env(cfg: &Config) {
    println!(
        "cargo:rustc-env=CFG_CARGO_FEATURES={:?}",
        cfg.cargo_features
    );
    println!("cargo:rustc-env=CFG_OPT_LEVEL={}", cfg.opt_level);
    println!(
        "cargo:rustc-env=CFG_TARGET_FEATURES={:?}",
        cfg.target_features
    );
}

/// Configure whether or not `f16` and `f128` support should be enabled.
fn emit_f16_f128_cfg(cfg: &Config) {
    println!("cargo:rustc-check-cfg=cfg(f16_enabled)");
    println!("cargo:rustc-check-cfg=cfg(f128_enabled)");

    // `unstable-float` enables these features.
    if !cfg!(feature = "unstable-float") {
        return;
    }

    /* See the compiler-builtins configure file for info about the meaning of these options */

    // If the feature is set, disable both of these types.
    let no_f16_f128 = cfg.cargo_features.iter().any(|s| s == "no-f16-f128");

    println!("cargo:rustc-check-cfg=cfg(f16_enabled)");
    if cfg.reliable_f16 && !no_f16_f128 {
        println!("cargo:rustc-cfg=f16_enabled");
    }

    println!("cargo:rustc-check-cfg=cfg(f128_enabled)");
    if cfg.reliable_f128 && !no_f16_f128 {
        println!("cargo:rustc-cfg=f128_enabled");
    }
}
