use folk_plugin_process::config::{ProcessConfig, RestartPolicy};
use folk_plugin_process::folk_plugin_factory;
use serde_json::json;

// Regression: an absent `[process]` section reaches the factory as an empty
// JSON object `{}` (folk-builder passes `{}` for every missing section so
// plugins can start on defaults). The factory must accept it and supervise
// nothing — instead of failing with "missing field `processes`".
#[test]
fn factory_accepts_empty_config() {
    let plugin = folk_plugin_factory().create(json!({}));
    assert!(
        plugin.is_ok(),
        "empty [process] config must succeed, got: {:?}",
        plugin.err()
    );
}

#[test]
fn empty_config_deserializes_to_no_processes() {
    let cfg: ProcessConfig = serde_json::from_value(json!({})).expect("empty object must parse");
    assert!(cfg.processes.is_empty());
}

#[test]
fn explicit_empty_processes_array_is_accepted() {
    let cfg: ProcessConfig =
        serde_json::from_value(json!({ "processes": [] })).expect("empty array must parse");
    assert!(cfg.processes.is_empty());
    assert!(
        folk_plugin_factory()
            .create(json!({ "processes": [] }))
            .is_ok()
    );
}

#[test]
fn process_def_fields_and_defaults_parse() {
    let cfg: ProcessConfig = serde_json::from_value(json!({
        "processes": [{
            "name": "queue-worker",
            "command": "php artisan queue:work",
            "restart": "always",
            "max_restarts": 10,
            "restart_delay": "5s"
            // stop_timeout / stop_signal / numprocs / env / logging omitted -> defaults
        }]
    }))
    .expect("valid process def must parse");

    assert_eq!(cfg.processes.len(), 1);
    let def = &cfg.processes[0];
    assert_eq!(def.name, "queue-worker");
    assert_eq!(def.restart, RestartPolicy::Always);
    assert_eq!(def.max_restarts, 10);
    // serde defaults applied for omitted fields
    assert_eq!(def.numprocs, 1);
    assert!(def.directory.is_none());
}

// The error must surface the underlying serde reason, not just the generic
// "invalid [process] configuration" wrapper (bonus from folk-releases#36).
#[test]
fn malformed_process_reports_underlying_serde_error() {
    // missing required `command`
    let result = folk_plugin_factory().create(
        json!({ "processes": [{ "name": "x", "restart": "never", "max_restarts": 1, "restart_delay": "1s" }] }),
    );
    let err = match result {
        Ok(_) => panic!("missing required field must fail"),
        Err(e) => e,
    };
    let msg = format!("{err}");
    assert!(
        msg.contains("invalid [process] configuration"),
        "should keep the section context, got: {msg}"
    );
    assert!(
        msg.contains("command"),
        "should surface the underlying serde reason naming the field, got: {msg}"
    );
}
