pub mod archive_metadata;

use std::{env, ffi, fs, io, process};

use do_not_use_println_but_cargo_directive_or_eprintln::*;
#[rustfmt::skip]
mod do_not_use_println_but_cargo_directive_or_eprintln {
    macro_rules! cargo_directive {(
        $kind:expr => $($contents:tt)*
    ) => ({
        let contents = ::std::format!($($contents)*);
        let contents = contents.trim();
        assert_eq!(contents.contains('\n'), false);
        ::std::println!(
            ::core::concat!("cargo:", $kind, "={}"), contents,
        );
    })}
    pub(in crate) use cargo_directive;
    #[allow(unused)]
    pub(in crate) use cargo_directive as println; // render println ambiguous to prevent misusage
}

macro_rules! warn_ {( $($msg:tt)* ) => ({
    let msg = ::std::format!($($msg)*);
    msg.lines().for_each(|line| {
        cargo_directive!("warning"=>
            "[{}] {}",
            env!("CARGO_PKG_NAME"),
            line,
        );
    });
})}

use warn_ as warn;

pub fn fetch_rust_edition() -> Option<String> {
    let manifest_path = env::var("CARGO_MANIFEST_PATH").ok()?;
    let cargo_toml: toml::Value = toml::from_str(&fs::read_to_string(manifest_path).ok()?).ok()?;

    // All Cargo.tomls should have a package table if they run a build script.
    let package_def = cargo_toml.get("package")?;

    let current_edition = package_def
        .get("edition")
        .and_then(|ed_val| ed_val.as_str())
        .unwrap_or_else(|| {
            eprintln!("Edition not declared in Cargo.toml, falling back to default.");
            "2015"
        });

    Some(current_edition.to_string())
}

// TODO(baxterjo): Ideally this can be replaced with `built` info after
// https://github.com/lukaslueg/built/pull/92 is merged. For now this function is identical to how
// the `built` crate gets rustc version.
pub fn get_rust_version_from_cmd(rustc: &ffi::OsStr) -> io::Result<String> {
    let output = process::Command::new(rustc).arg("-V").output()?;
    let mut v = String::from_utf8(output.stdout).unwrap();
    v.pop(); // remove newline
    Ok(v)
}
