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

fn python_config_from_exe(python: &str) -> Option<PathBuf> {
    let exe = Path::new(python);
    let file = exe.file_name()?.to_string_lossy();
    let config_name = format!("{file}-config");
    let candidate = exe.with_file_name(config_name);
    if candidate.exists() {
        Some(candidate)
    } else {
        None
    }
}

fn python_config_from_sysconfig(python: &str) -> Option<PathBuf> {
    let output = Command::new(python)
        .args([
            "-c",
            "import sys, sysconfig; \
print(sysconfig.get_config_var('BINDIR') or ''); \
print(sys.version_info.major); \
print(sys.version_info.minor);",
        ])
        .output()
        .ok()?;
    if !output.status.success() {
        return None;
    }
    let stdout = String::from_utf8_lossy(&output.stdout);
    let mut lines = stdout.lines();
    let bindir = lines.next()?.trim();
    let major = lines.next()?.trim();
    let minor = lines.next()?.trim();
    if bindir.is_empty() {
        return None;
    }
    let candidates = [
        format!("python{major}.{minor}-config"),
        format!("python{major}-config"),
        "python3-config".to_string(),
        "python-config".to_string(),
    ];
    for name in candidates {
        let candidate = Path::new(bindir).join(name);
        if candidate.exists() {
            return Some(candidate);
        }
    }
    None
}

fn main() {
    pyo3_build_config::add_extension_module_link_args();

    if cfg!(target_os = "windows") {
        println!("cargo:warning=Windows では python3-config が利用できないため埋め込みフラグをスキップします");
        return;
    }

    let profile = env::var("PROFILE").unwrap_or_default();
    if profile == "release" {
        return;
    }

    let python = env::var("PYO3_PYTHON").unwrap_or_else(|_| "python3".to_string());
    let mut config = python_config_from_exe(&python)
        .or_else(|| python_config_from_sysconfig(&python))
        .unwrap_or_else(|| PathBuf::from("python3-config"));
    if config.as_path() == Path::new("python3-config") {
        let system_config = PathBuf::from("/usr/bin/python3-config");
        if system_config.exists() {
            config = system_config;
        }
    }
    let output = match Command::new(&config)
        .args(["--ldflags", "--embed"])
        .output()
    {
        Ok(output) => output,
        Err(err) => {
            println!(
                "cargo:warning={} の実行に失敗しました: {err}",
                config.to_string_lossy()
            );
            return;
        }
    };
    if !output.status.success() {
        println!(
            "cargo:warning={} --ldflags --embed が失敗しました (status: {:?})",
            config.to_string_lossy(),
            output.status.code()
        );
        return;
    }

    let stdout = String::from_utf8_lossy(&output.stdout);
    for token in stdout.split_whitespace() {
        if let Some(path) = token.strip_prefix("-L") {
            println!("cargo:rustc-link-search=native={path}");
        } else if let Some(lib) = token.strip_prefix("-l") {
            println!("cargo:rustc-link-lib={lib}");
        }
    }
}
