use folk_builder::config::{BuildConfig, manifest_from_str};

#[test]
fn parse_sample_config() {
    let toml_str = r#"
[build]
output = "folk-custom"
rust_version = "1.85"

[[plugin]]
crate_name = "folk_plugin_http"
version = "0.1.0"
config_key = "http"

[[plugin]]
crate_name = "folk_plugin_jobs"
version = "0.1.0"
config_key = "jobs"

[[plugin]]
crate_name = "my_custom_plugin"
path = "../my-plugin"
"#;

    let cfg: BuildConfig = toml::from_str(toml_str).unwrap();
    assert_eq!(cfg.build.output, "folk-custom");
    assert_eq!(cfg.build.rust_version, "1.85");
    assert_eq!(cfg.plugin.len(), 3);

    assert_eq!(cfg.plugin[0].crate_name, "folk_plugin_http");
    assert_eq!(cfg.plugin[0].version.as_deref(), Some("0.1.0"));
    assert_eq!(cfg.plugin[0].config_key, "http");

    assert_eq!(cfg.plugin[1].crate_name, "folk_plugin_jobs");
    assert_eq!(cfg.plugin[1].config_key, "jobs");

    assert_eq!(cfg.plugin[2].crate_name, "my_custom_plugin");
    assert_eq!(cfg.plugin[2].path.as_deref(), Some("../my-plugin"));
    assert!(cfg.plugin[2].version.is_none());
}

#[test]
fn manifest_parses_string_and_table_plugins() {
    // Mirrors build-manifest.toml: string-form plugins, then a table-form
    // plugin with features. Table-form entries must come last (TOML rule).
    let manifest = r#"
[release]
version = "0.1.17"

[builder]
version = "0.2.*"

[plugins]
folk-plugin-http = "0.4.*"
folk-plugin-grpc = "0.2.*"

[plugins.folk-plugin-jobs]
version = "0.4.*"
features = ["redis", "embedded"]
"#;

    let cfg = manifest_from_str(manifest).unwrap();
    // Output is always "folk" for manifest-driven builds.
    assert_eq!(cfg.build.output, "folk");
    assert_eq!(cfg.plugin.len(), 3);

    let http = cfg
        .plugin
        .iter()
        .find(|p| p.crate_name == "folk-plugin-http")
        .unwrap();
    // "0.4.*" → cargo requirement "0.4".
    assert_eq!(http.version.as_deref(), Some("0.4"));
    assert_eq!(http.config_key, "http");
    assert!(http.features.is_empty());

    let jobs = cfg
        .plugin
        .iter()
        .find(|p| p.crate_name == "folk-plugin-jobs")
        .unwrap();
    assert_eq!(jobs.version.as_deref(), Some("0.4"));
    assert_eq!(jobs.config_key, "jobs");
    assert_eq!(jobs.features, vec!["redis", "embedded"]);
}

#[test]
fn manifest_drives_codegen_with_features() {
    use folk_builder::codegen::generate_cargo_toml;

    let manifest = r#"
[plugins]
folk-plugin-http = "0.4.*"

[plugins.folk-plugin-jobs]
version = "0.4.*"
features = ["embedded"]
"#;
    let cfg = manifest_from_str(manifest).unwrap();
    let cargo = generate_cargo_toml(&cfg);
    assert!(
        cargo.contains(r#"folk-plugin-http = "0.4""#),
        "got: {cargo}"
    );
    assert!(
        cargo.contains(r#"folk-plugin-jobs = { version = "0.4", features = ["embedded"] }"#),
        "got: {cargo}"
    );
}

#[test]
fn default_rust_version() {
    let toml_str = r#"
[build]
output = "folk-minimal"
"#;

    let cfg: BuildConfig = toml::from_str(toml_str).unwrap();
    assert_eq!(cfg.build.rust_version, "1.85");
    assert!(cfg.plugin.is_empty());
}
