/// Drive `{{ owner_path }}::{{ ep_method }}` from Elixir.
///
/// This NIF is scheduled on the dirty CPU scheduler to avoid blocking
/// the BEAM scheduler during the (potentially long) run operation.
///
/// # Arguments
///
/// - `registrations` — Elixir list of `{method_name, metadata, handler}` tuples
///   where `handler` is an Elixir function/closure that accepts request JSON and returns response JSON.
{% for param in ep_params %}/// - `{{ param }}` — entrypoint parameter
{% endfor %}///
/// # Returns
/// `:ok` or `{:error, reason}` after the entrypoint completes.
#[rustler::nif(schedule = "DirtyCpu")]
pub fn {{ fn_name }}({{ param_sig }}) -> NifResult<Atom> {
    // Parse registrations from Elixir term
    let registration_list: Vec<rustler::Term<'_>> = registrations
        .decode::<Vec<rustler::Term<'_>>>()
        .unwrap_or_else(|_| vec![]);

    // Build the service owner from its constructor
    let mut owner = {{ owner_path }}::new();

    // Register handlers from Elixir registrations
    // Each registration entry is a tuple: {method_name, metadata, handler_pid}
    for reg_entry in registration_list {
        if let Ok((method_name, metadata, handler_pid)) = reg_entry.decode::<(String, rustler::Term<'_>, rustler::LocalPid)>()
        {
