//! Tests for profiles defined in config files.

use cargo_test_support::prelude::*;
use cargo_test_support::registry::Package;
use cargo_test_support::{basic_lib_manifest, paths, project, str};
use cargo_util_schemas::manifest::TomlDebugInfo;

// TODO: this should be remove once -Zprofile-rustflags is stabilized
#[cargo_test]
fn rustflags_works_with_zflag() {
    let p = project()
        .file(
            "Cargo.toml",
            r#"
                [package]
                name = "foo"
                version = "0.0.1"
                edition = "2015"
            "#,
        )
        .file("src/main.rs", "fn main() {}")
        .file(
            ".cargo/config.toml",
            r#"
                [profile.dev]
                rustflags = ["-C", "link-dead-code=yes"]
            "#,
        )
        .build();

    p.cargo("check -v")
        .masquerade_as_nightly_cargo(&["profile-rustflags"])
        .with_status(101)
        .with_stderr_data(str![[r#"
[ERROR] config profile `dev` is not valid (defined in `[ROOT]/foo/.cargo/config.toml`)

Caused by:
  feature `profile-rustflags` is required
...
"#]])
        .run();

    p.cargo("check -v -Zprofile-rustflags")
        .masquerade_as_nightly_cargo(&["profile-rustflags"])
        .with_stderr_data(str![[r#"
[CHECKING] foo v0.0.1 ([ROOT]/foo)
[RUNNING] `rustc --crate-name foo [..] -C link-dead-code=yes [..]`
[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s

"#]])
        .run();

    p.change_file(
        ".cargo/config.toml",
        r#"
            [unstable]
            profile-rustflags = true

            [profile.dev]
            rustflags = ["-C", "link-dead-code=yes"]
        "#,
    );

    p.cargo("check -v")
        .masquerade_as_nightly_cargo(&["profile-rustflags"])
        .with_stderr_data(str![[r#"
[FRESH] foo v0.0.1 ([ROOT]/foo)
[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s

"#]])
        .run();
}

#[cargo_test]
fn profile_config_validate_warnings() {
    let p = project()
        .file("Cargo.toml", &basic_lib_manifest("foo"))
        .file("src/lib.rs", "")
        .file(
            ".cargo/config.toml",
            r#"
                [profile.test]
                opt-level = 3

                [profile.asdf]
                opt-level = 3

                [profile.dev]
                bad-key = true

                [profile.dev.build-override]
                bad-key-bo = true

                [profile.dev.package.bar]
                bad-key-bar = true
            "#,
        )
        .build();

    p.cargo("build").with_stderr_data(str![[r#"
[WARNING] unused config key `profile.dev.bad-key` in `[ROOT]/foo/.cargo/config.toml`
[WARNING] unused config key `profile.dev.build-override.bad-key-bo` in `[ROOT]/foo/.cargo/config.toml`
[WARNING] unused config key `profile.dev.package.bar.bad-key-bar` in `[ROOT]/foo/.cargo/config.toml`
[COMPILING] foo v0.5.0 ([ROOT]/foo)
[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s

"#]].unordered()).run();
}

#[cargo_test]
fn profile_config_error_paths() {
    // Errors in config show where the error is located.
    let p = project()
        .file("Cargo.toml", &basic_lib_manifest("foo"))
        .file("src/lib.rs", "")
        .file(
            ".cargo/config.toml",
            r#"
                [profile.dev]
                opt-level = 3
            "#,
        )
        .file(
            paths::home().join(".cargo/config.toml"),
            r#"
            [profile.dev]
            rpath = "foo"
            "#,
        )
        .build();

    p.cargo("build")
        .with_status(101)
        .with_stderr_data(str![[r#"
[ERROR] error in [ROOT]/foo/.cargo/config.toml: could not load config key `profile.dev`

Caused by:
  error in [ROOT]/home/.cargo/config.toml: `profile.dev.rpath` expected true/false, but found a string

"#]])
        .run();
}

#[cargo_test]
fn profile_config_validate_errors() {
    let p = project()
        .file("Cargo.toml", &basic_lib_manifest("foo"))
        .file("src/lib.rs", "")
        .file(
            ".cargo/config.toml",
            r#"
                [profile.dev.package.foo]
                panic = "abort"
            "#,
        )
        .build();

    p.cargo("build")
        .with_status(101)
        .with_stderr_data(str![[r#"
[ERROR] config profile `dev` is not valid (defined in `[ROOT]/foo/.cargo/config.toml`)

Caused by:
  `panic` may not be specified in a `package` profile

"#]])
        .run();
}

#[cargo_test]
fn profile_config_syntax_errors() {
    let p = project()
        .file("Cargo.toml", &basic_lib_manifest("foo"))
        .file("src/lib.rs", "")
        .file(
            ".cargo/config.toml",
            r#"
                [profile.dev]
                codegen-units = "foo"
            "#,
        )
        .build();

    p.cargo("build")
        .with_status(101)
        .with_stderr_data(str![[r#"
[ERROR] error in [ROOT]/foo/.cargo/config.toml: could not load config key `profile.dev`

Caused by:
  error in [ROOT]/foo/.cargo/config.toml: `profile.dev.codegen-units` expected an integer, but found a string

"#]])
        .run();
}

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

            [dependencies]
            bar = { path = "bar" }
            "#,
        )
        .file(
            ".cargo/config.toml",
            r#"
                [profile.dev.package.bar]
                opt-level = 3

                [profile.dev.package."bar:0.5.0"]
                opt-level = 3
            "#,
        )
        .file("src/lib.rs", "")
        .file("bar/Cargo.toml", &basic_lib_manifest("bar"))
        .file("bar/src/lib.rs", "")
        .build();

    // Unfortunately this doesn't tell you which file, hopefully it's not too
    // much of a problem.
    p.cargo("build -v")
        .with_status(101)
        .with_stderr_data(str![[r#"
[LOCKING] 1 package to latest compatible version
[ERROR] multiple package overrides in profile `dev` match package `bar v0.5.0 ([ROOT]/foo/bar)`
found package specs: bar, bar@0.5.0

"#]])
        .run();
}

#[cargo_test]
fn profile_config_all_options() {
    // Ensure all profile options are supported.
    let p = project()
        .file("src/main.rs", "fn main() {}")
        .file(
            ".cargo/config.toml",
            r#"
            [profile.release]
            opt-level = 1
            debug = true
            debug-assertions = true
            overflow-checks = false
            rpath = true
            lto = true
            codegen-units = 2
            panic = "abort"
            incremental = true
            "#,
        )
        .build();

    p.cargo("build --release -v")
        .env_remove("CARGO_INCREMENTAL")
        .with_stderr_data(str![[r#"
[COMPILING] foo v0.0.1 ([ROOT]/foo)
[RUNNING] `rustc --crate-name foo [..] -C opt-level=1 -C panic=abort -C lto[..]-C codegen-units=2 -C debuginfo=2 [..]-C debug-assertions=on -C overflow-checks=off [..]-C rpath --out-dir [ROOT]/foo/target/release/deps -C incremental=[ROOT]/foo/target/release/incremental[..]`
[FINISHED] `release` profile [optimized + debuginfo] target(s) in [ELAPSED]s

"#]])
        .run();
}

#[cargo_test]
fn profile_config_override_precedence() {
    // Config values take precedence over manifest values.
    let p = project()
        .file(
            "Cargo.toml",
            r#"
                [package]
                name = "foo"
                version = "0.0.1"
                edition = "2015"

                [dependencies]
                bar = {path = "bar"}

                [profile.dev]
                codegen-units = 2

                [profile.dev.package.bar]
                opt-level = 3
            "#,
        )
        .file("src/lib.rs", "")
        .file("bar/Cargo.toml", &basic_lib_manifest("bar"))
        .file("bar/src/lib.rs", "")
        .file(
            ".cargo/config.toml",
            r#"
                [profile.dev.package.bar]
                opt-level = 2
            "#,
        )
        .build();

    p.cargo("build -v")
        .with_stderr_data(str![[r#"
[LOCKING] 1 package to latest compatible version
[COMPILING] bar v0.5.0 ([ROOT]/foo/bar)
[RUNNING] `rustc --crate-name bar [..] -C opt-level=2[..]-C codegen-units=2 [..]`
[COMPILING] foo v0.0.1 ([ROOT]/foo)
[RUNNING] `rustc --crate-name foo [..]-C codegen-units=2 [..]`
[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s

"#]])
        .run();
}

#[expect(deprecated)]
#[cargo_test]
fn profile_config_no_warn_unknown_override() {
    let p = project()
        .file("Cargo.toml", &basic_lib_manifest("foo"))
        .file("src/lib.rs", "")
        .file(
            ".cargo/config.toml",
            r#"
                [profile.dev.package.bar]
                codegen-units = 4
            "#,
        )
        .build();

    p.cargo("build")
        .with_stderr_does_not_contain("[..]warning[..]")
        .run();
}

#[cargo_test]
fn profile_config_mixed_types() {
    let p = project()
        .file("Cargo.toml", &basic_lib_manifest("foo"))
        .file("src/lib.rs", "")
        .file(
            ".cargo/config.toml",
            r#"
                [profile.dev]
                opt-level = 3
            "#,
        )
        .file(
            paths::home().join(".cargo/config.toml"),
            r#"
            [profile.dev]
            opt-level = 's'
            "#,
        )
        .build();

    p.cargo("build -v")
        .with_stderr_data(str![[r#"
[COMPILING] foo v0.5.0 ([ROOT]/foo)
[RUNNING] `rustc [..]-C opt-level=3 [..]`
[FINISHED] `dev` profile [optimized + debuginfo] target(s) in [ELAPSED]s

"#]])
        .run();
}

#[cargo_test]
fn named_config_profile() {
    // Exercises config named profiles.
    // foo -> middle -> bar -> dev
    // middle exists in Cargo.toml, the others in .cargo/config.toml
    use super::config::GlobalContextBuilder;
    use cargo::core::compiler::CompileKind;
    use cargo::core::profiles::{Profiles, UnitFor};
    use cargo::core::{PackageId, Workspace};
    use cargo::util::interning::InternedString;
    use std::fs;
    paths::root().join(".cargo").mkdir_p();
    fs::write(
        paths::root().join(".cargo/config.toml"),
        r#"
            [profile.foo]
            inherits = "middle"
            codegen-units = 2
            [profile.foo.build-override]
            codegen-units = 6
            [profile.foo.package.dep]
            codegen-units = 7

            [profile.middle]
            inherits = "bar"
            codegen-units = 3

            [profile.bar]
            inherits = "dev"
            codegen-units = 4
            debug = 1
        "#,
    )
    .unwrap();
    fs::write(
        paths::root().join("Cargo.toml"),
        r#"
            [workspace]

            [profile.middle]
            inherits = "bar"
            codegen-units = 1
            opt-level = 1
            [profile.middle.package.dep]
            overflow-checks = false

            [profile.foo.build-override]
            codegen-units = 5
            debug-assertions = false
            [profile.foo.package.dep]
            codegen-units = 8
        "#,
    )
    .unwrap();
    let gctx = GlobalContextBuilder::new().build();
    let profile_name = InternedString::new("foo");
    let ws = Workspace::new(&paths::root().join("Cargo.toml"), &gctx).unwrap();
    let profiles = Profiles::new(&ws, profile_name).unwrap();

    let crates_io = cargo::core::SourceId::crates_io(&gctx).unwrap();
    let a_pkg = PackageId::try_new("a", "0.1.0", crates_io).unwrap();
    let dep_pkg = PackageId::try_new("dep", "0.1.0", crates_io).unwrap();

    // normal package
    let kind = CompileKind::Host;
    let p = profiles.get_profile(a_pkg, true, true, UnitFor::new_normal(kind), kind);
    assert_eq!(p.name, "foo");
    assert_eq!(p.codegen_units, Some(2)); // "foo" from config
    assert_eq!(p.opt_level, "1"); // "middle" from manifest
    assert_eq!(p.debuginfo.into_inner(), TomlDebugInfo::Limited); // "bar" from config
    assert_eq!(p.debug_assertions, true); // "dev" built-in (ignore build-override)
    assert_eq!(p.overflow_checks, true); // "dev" built-in (ignore package override)

    // build-override
    let bo = profiles.get_profile(a_pkg, true, true, UnitFor::new_host(false, kind), kind);
    assert_eq!(bo.name, "foo");
    assert_eq!(bo.codegen_units, Some(6)); // "foo" build override from config
    assert_eq!(bo.opt_level, "0"); // default to zero
    assert_eq!(bo.debuginfo.into_inner(), TomlDebugInfo::Limited); // SAME as normal
    assert_eq!(bo.debug_assertions, false); // "foo" build override from manifest
    assert_eq!(bo.overflow_checks, true); // SAME as normal

    // package overrides
    let po = profiles.get_profile(dep_pkg, false, true, UnitFor::new_normal(kind), kind);
    assert_eq!(po.name, "foo");
    assert_eq!(po.codegen_units, Some(7)); // "foo" package override from config
    assert_eq!(po.opt_level, "1"); // SAME as normal
    assert_eq!(po.debuginfo.into_inner(), TomlDebugInfo::Limited); // SAME as normal
    assert_eq!(po.debug_assertions, true); // SAME as normal
    assert_eq!(po.overflow_checks, false); // "middle" package override from manifest
}

#[cargo_test]
fn named_env_profile() {
    // Environment variables used to define a named profile.
    let p = project()
        .file(
            "Cargo.toml",
            r#"
            [package]
            name = "foo"
            version = "0.1.0"
            edition = "2015"
            "#,
        )
        .file("src/lib.rs", "")
        .build();

    p.cargo("build -v --profile=other")
        .env("CARGO_PROFILE_OTHER_CODEGEN_UNITS", "1")
        .env("CARGO_PROFILE_OTHER_INHERITS", "dev")
        .with_stderr_data(str![[r#"
[COMPILING] foo v0.1.0 ([ROOT]/foo)
[RUNNING] `rustc [..]-C codegen-units=1 [..]`
[FINISHED] `other` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s

"#]])
        .run();
}

#[expect(deprecated)]
#[cargo_test]
fn test_with_dev_profile() {
    // The `test` profile inherits from `dev` for both local crates and
    // dependencies.
    Package::new("somedep", "1.0.0").publish();
    let p = project()
        .file(
            "Cargo.toml",
            r#"
            [package]
            name = "foo"
            version = "0.1.0"
            edition = "2015"

            [dependencies]
            somedep = "1.0"
            "#,
        )
        .file("src/lib.rs", "")
        .build();
    p.cargo("test --lib --no-run -v")
        .env("CARGO_PROFILE_DEV_DEBUG", "0")
        .with_stderr_data(str![[r#"
[UPDATING] `dummy-registry` index
[LOCKING] 1 package to latest compatible version
[DOWNLOADING] crates ...
[DOWNLOADED] somedep v1.0.0 (registry `dummy-registry`)
[COMPILING] somedep v1.0.0
[RUNNING] `rustc --crate-name somedep [..]`
[COMPILING] foo v0.1.0 ([ROOT]/foo)
[RUNNING] `rustc --crate-name foo [..]`
[FINISHED] `test` profile [unoptimized] target(s) in [ELAPSED]s
[EXECUTABLE] `[ROOT]/foo/target/debug/deps/foo-[HASH][EXE]`

"#]])
        .with_stdout_does_not_contain("[..] -C debuginfo=0[..]")
        .run();
}
