//! Tests for cfg() expressions.

use cargo_test_support::prelude::*;
use cargo_test_support::registry::Package;
use cargo_test_support::rustc_host;
use cargo_test_support::{basic_manifest, project, str};

#[cargo_test]
fn cfg_easy() {
    let p = project()
        .file(
            "Cargo.toml",
            r#"
                [package]
                name = "a"
                version = "0.0.1"
                edition = "2015"
                authors = []

                [target.'cfg(unix)'.dependencies]
                b = { path = 'b' }
                [target."cfg(windows)".dependencies]
                b = { path = 'b' }
            "#,
        )
        .file("src/lib.rs", "extern crate b;")
        .file("b/Cargo.toml", &basic_manifest("b", "0.0.1"))
        .file("b/src/lib.rs", "")
        .build();
    p.cargo("check -v").run();
}

#[cargo_test]
fn dont_include() {
    let other_family = if cfg!(unix) { "windows" } else { "unix" };
    let p = project()
        .file(
            "Cargo.toml",
            &format!(
                r#"
                    [package]
                    name = "a"
                    version = "0.0.1"
                    edition = "2015"
                    authors = []

                    [target.'cfg({})'.dependencies]
                    b = {{ path = 'b' }}
                "#,
                other_family
            ),
        )
        .file("src/lib.rs", "")
        .file("b/Cargo.toml", &basic_manifest("b", "0.0.1"))
        .file("b/src/lib.rs", "")
        .build();
    p.cargo("check")
        .with_stderr_data(str![[r#"
[LOCKING] 1 package to latest compatible version
[CHECKING] a v0.0.1 ([ROOT]/foo)
[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s

"#]])
        .run();
}

#[cargo_test]
fn works_through_the_registry() {
    Package::new("baz", "0.1.0").publish();
    Package::new("bar", "0.1.0")
        .target_dep("baz", "0.1.0", "cfg(unix)")
        .target_dep("baz", "0.1.0", "cfg(windows)")
        .publish();

    let p = project()
        .file(
            "Cargo.toml",
            r#"
                [package]
                name = "foo"
                version = "0.0.1"
                edition = "2015"
                authors = []

                [dependencies]
                bar = "0.1.0"
            "#,
        )
        .file(
            "src/lib.rs",
            "#[allow(unused_extern_crates)] extern crate bar;",
        )
        .build();

    p.cargo("check")
        .with_stderr_data(str![[r#"
[UPDATING] `dummy-registry` index
[LOCKING] 2 packages to latest compatible versions
[DOWNLOADING] crates ...
[DOWNLOADED] baz v0.1.0 (registry `dummy-registry`)
[DOWNLOADED] bar v0.1.0 (registry `dummy-registry`)
[CHECKING] baz v0.1.0
[CHECKING] bar v0.1.0
[CHECKING] foo v0.0.1 ([ROOT]/foo)
[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s

"#]])
        .run();
}

#[cargo_test]
fn ignore_version_from_other_platform() {
    let this_family = if cfg!(unix) { "unix" } else { "windows" };
    let other_family = if cfg!(unix) { "windows" } else { "unix" };
    Package::new("bar", "0.1.0").publish();
    Package::new("bar", "0.2.0").publish();

    let p = project()
        .file(
            "Cargo.toml",
            &format!(
                r#"
                    [package]
                    name = "foo"
                    version = "0.0.1"
                    edition = "2015"
                    authors = []

                    [target.'cfg({})'.dependencies]
                    bar = "0.1.0"

                    [target.'cfg({})'.dependencies]
                    bar = "0.2.0"
                "#,
                this_family, other_family
            ),
        )
        .file(
            "src/lib.rs",
            "#[allow(unused_extern_crates)] extern crate bar;",
        )
        .build();

    p.cargo("check")
        .with_stderr_data(str![[r#"
[UPDATING] `dummy-registry` index
[LOCKING] 2 packages to latest compatible versions
[ADDING] bar v0.1.0 (available: v0.2.0)
[DOWNLOADING] crates ...
[DOWNLOADED] bar v0.1.0 (registry `dummy-registry`)
[CHECKING] bar v0.1.0
[CHECKING] foo v0.0.1 ([ROOT]/foo)
[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s

"#]])
        .run();
}

#[cargo_test]
fn bad_target_spec() {
    let p = project()
        .file(
            "Cargo.toml",
            r#"
                [package]
                name = "foo"
                version = "0.0.1"
                edition = "2015"
                authors = []

                [target.'cfg(4)'.dependencies]
                bar = "0.1.0"
            "#,
        )
        .file("src/lib.rs", "")
        .build();

    p.cargo("check")
        .with_status(101)
        .with_stderr_data(str![[r#"
[ERROR] failed to parse manifest at `[ROOT]/foo/Cargo.toml`

Caused by:
  failed to parse `4` as a cfg expression: unexpected character `4` in cfg, expected parens, a comma, an identifier, or a string

"#]])
        .run();
}

#[cargo_test]
fn bad_target_spec2() {
    let p = project()
        .file(
            "Cargo.toml",
            r#"
                [package]
                name = "foo"
                version = "0.0.1"
                edition = "2015"
                authors = []

                [target.'cfg(bar =)'.dependencies]
                baz = "0.1.0"
            "#,
        )
        .file("src/lib.rs", "")
        .build();

    p.cargo("check")
        .with_status(101)
        .with_stderr_data(str![[r#"
[ERROR] failed to parse manifest at `[ROOT]/foo/Cargo.toml`

Caused by:
  failed to parse `bar =` as a cfg expression: expected a string, but cfg expression ended

"#]])
        .run();
}

#[cargo_test]
fn multiple_match_ok() {
    let p = project()
        .file(
            "Cargo.toml",
            &format!(
                r#"
                    [package]
                    name = "a"
                    version = "0.0.1"
                    edition = "2015"
                    authors = []

                    [target.'cfg(unix)'.dependencies]
                    b = {{ path = 'b' }}
                    [target.'cfg(target_family = "unix")'.dependencies]
                    b = {{ path = 'b' }}
                    [target."cfg(windows)".dependencies]
                    b = {{ path = 'b' }}
                    [target.'cfg(target_family = "windows")'.dependencies]
                    b = {{ path = 'b' }}
                    [target."cfg(any(windows, unix))".dependencies]
                    b = {{ path = 'b' }}

                    [target.{}.dependencies]
                    b = {{ path = 'b' }}
                "#,
                rustc_host()
            ),
        )
        .file("src/lib.rs", "extern crate b;")
        .file("b/Cargo.toml", &basic_manifest("b", "0.0.1"))
        .file("b/src/lib.rs", "")
        .build();
    p.cargo("check -v").run();
}

#[cargo_test]
fn any_ok() {
    let p = project()
        .file(
            "Cargo.toml",
            r#"
                [package]
                name = "a"
                version = "0.0.1"
                edition = "2015"
                authors = []

                [target."cfg(any(windows, unix))".dependencies]
                b = { path = 'b' }
            "#,
        )
        .file("src/lib.rs", "extern crate b;")
        .file("b/Cargo.toml", &basic_manifest("b", "0.0.1"))
        .file("b/src/lib.rs", "")
        .build();
    p.cargo("check -v").run();
}

// https://github.com/rust-lang/cargo/issues/5313
#[cargo_test]
#[cfg(all(target_arch = "x86_64", target_os = "linux", target_env = "gnu"))]
fn cfg_looks_at_rustflags_for_target() {
    let p = project()
        .file(
            "Cargo.toml",
            r#"
                [package]
                name = "a"
                version = "0.0.1"
                edition = "2015"
                authors = []

                [target.'cfg(with_b)'.dependencies]
                b = { path = 'b' }
            "#,
        )
        .file(
            "src/main.rs",
            r#"
                #[cfg(with_b)]
                extern crate b;

                fn main() { b::foo(); }
            "#,
        )
        .file("b/Cargo.toml", &basic_manifest("b", "0.0.1"))
        .file("b/src/lib.rs", "pub fn foo() {}")
        .build();

    p.cargo("check --target x86_64-unknown-linux-gnu")
        .env("RUSTFLAGS", "--cfg with_b")
        .run();
}

#[cargo_test]
fn bad_cfg_discovery() {
    // Check error messages when `rustc -v` and `rustc --print=*` parsing fails.
    //
    // This is a `rustc` replacement which behaves differently based on an
    // environment variable.
    let p = project()
        .at("compiler")
        .file("Cargo.toml", &basic_manifest("compiler", "0.1.0"))
        .file(
            "src/main.rs",
            r#"
            fn run_rustc() -> String {
                let mut cmd = std::process::Command::new("rustc");
                for arg in std::env::args_os().skip(1) {
                    cmd.arg(arg);
                }
                String::from_utf8(cmd.output().unwrap().stdout).unwrap()
            }

            fn main() {
                let mode = std::env::var("FUNKY_MODE").unwrap();
                if mode == "bad-version" {
                    println!("foo");
                    return;
                }
                if std::env::args_os().any(|a| a == "-vV") {
                    print!("{}", run_rustc());
                    return;
                }
                if mode == "no-crate-types" {
                    return;
                }
                if mode == "bad-crate-type" {
                    println!("foo");
                    return;
                }
                let output = run_rustc();
                let mut lines = output.lines();
                let sysroot = loop {
                    let line = lines.next().unwrap();
                    if line.contains("___") {
                        println!("{}", line);
                    } else {
                        break line;
                    }
                };
                if mode == "no-sysroot" {
                    return;
                }
                println!("{}", sysroot);

                if mode == "no-split-debuginfo" {
                    return;
                }
                loop {
                    let line = lines.next().unwrap();
                    if line == "___" {
                        println!("\n{line}");
                        break;
                    } else {
                        // As the number split-debuginfo options varies,
                        // concat them into one line.
                        print!("{line},");
                    }
                };

                if mode != "bad-cfg" {
                    panic!("unexpected");
                }
                println!("123");
            }
            "#,
        )
        .build();
    p.cargo("build").run();
    let funky_rustc = p.bin("compiler");

    let p = project().file("src/lib.rs", "").build();

    p.cargo("check")
        .env("RUSTC", &funky_rustc)
        .env("FUNKY_MODE", "bad-version")
        .with_status(101)
        .with_stderr_data(str![[r#"
[ERROR] `rustc -vV` didn't have a line for `host:`, got:
foo


"#]])
        .run();

    p.cargo("check")
        .env("RUSTC", &funky_rustc)
        .env("FUNKY_MODE", "no-crate-types")
        .with_status(101)
        .with_stderr_data(str![[r#"
[ERROR] malformed output when learning about crate-type bin information
command was: `[ROOT]/compiler/target/debug/compiler[..] --crate-name ___ [..]`
(no output received)

"#]])
        .run();

    p.cargo("check")
        .env("RUSTC", &funky_rustc)
        .env("FUNKY_MODE", "no-sysroot")
        .with_status(101)
        .with_stderr_data(str![[r#"
[ERROR] output of --print=sysroot missing when learning about target-specific information from rustc
command was: `[ROOT]/compiler/target/debug/compiler[..]--crate-type [..]`

--- stdout
___[EXE]
lib___.rlib
[..]___.[..]
[..]___.[..]
[..]___.[..]
[..]___.[..]


"#]])
        .run();

    p.cargo("check")
        .env("RUSTC", &funky_rustc)
        .env("FUNKY_MODE", "no-split-debuginfo")
        .with_status(101)
        .with_stderr_data(str![[r#"
[ERROR] output of --print=split-debuginfo missing when learning about target-specific information from rustc
command was: `[ROOT]/compiler/target/debug/compiler[..]--crate-type [..]`

--- stdout
___[EXE]
lib___.rlib
[..]___.[..]
[..]___.[..]
[..]___.[..]
[..]___.[..]
[..]


"#]])
        .run();

    p.cargo("check")
        .env("RUSTC", &funky_rustc)
        .env("FUNKY_MODE", "bad-cfg")
        .with_status(101)
        .with_stderr_data(str![[r#"
[ERROR] failed to parse the cfg from `rustc --print=cfg`, got:
___[EXE]
lib___.rlib
[..]___.[..]
[..]___.[..]
[..]___.[..]
[..]___.[..]
[..]
[..],[..]
___
123


Caused by:
  failed to parse `123` as a cfg expression: unexpected character `1` in cfg, expected parens, a comma, an identifier, or a string

"#]])
        .run();
}

#[cargo_test]
fn exclusive_dep_kinds() {
    // Checks for a bug where the same package with different cfg expressions
    // was not being filtered correctly.
    Package::new("bar", "1.0.0").publish();
    let p = project()
        .file(
            "Cargo.toml",
            r#"
                [package]
                name = "foo"
                version = "0.1.0"
                edition = "2015"

                [target.'cfg(abc)'.dependencies]
                bar = "1.0"

                [target.'cfg(not(abc))'.build-dependencies]
                bar = "1.0"
            "#,
        )
        .file("src/lib.rs", "")
        .file("build.rs", "extern crate bar; fn main() {}")
        .build();

    p.cargo("check").run();
    p.change_file("src/lib.rs", "extern crate bar;");
    p.cargo("check")
        .with_status(101)
        // can't find crate for `bar`
        .with_stderr_data(str![[r#"
[COMPILING] foo v0.1.0 ([ROOT]/foo)
error[E0463]: can't find crate for `bar`
...
"#]])
        .run();
}
