
#include <string.h>
#include "{{ filename }}.h"

int {{ function_name }}_init({{ function_name }}_arg_t* arg, {{ function_name }}_res_t* res, {{ function_name }}_work_t* work) {
    if (!arg || !res || !work) {
        return -1; // Invalid pointers
    }

    /* Initialize inputs */
    memset(arg, 0, sizeof({{ function_name }}_arg_t));

    /* Initialize outputs */
    memset(res, 0, sizeof({{ function_name }}_res_t));

    /* Nonzero assignments */
{% for assignment in assignments %}
    {{ assignment.path }} = {{ assignment.value }};
{% endfor %}

    _Static_assert(sizeof({{ function_name }}_arg_t) == {{ input_size }} * sizeof(float),
        "Non-contiguous arg struct; please enable -fpack-struct or equivalent.");

    _Static_assert(sizeof({{ function_name }}_res_t) == {{ output_size }} * sizeof(float),
        "Non-contiguous res struct; please enable -fpack-struct or equivalent.");

    return 0;
}

int {{ function_name }}_step({{ function_name }}_arg_t* arg, {{ function_name }}_res_t* res, {{ function_name }}_work_t* work) {
    if (!arg || !res || !work) {
        return -1; // Invalid pointers
    }

    // Marshal inputs to CasADi format
    const {{ float_type }}* kernel_arg[{{ function_name }}_SZ_ARG];
{% for input in inputs | selectattr('ctx_type', 'ne', 'none') %}
{%- if input.ctx_type == "leaf" %}
    kernel_arg[{{ loop.index0 }}] = {% if input.is_addr %}&{% endif %}arg->{{ input.name }};
{%- elif input.ctx_type == "list" %}
{# Pointer casting - array decays to pointer #}
    kernel_arg[{{ loop.index0 }}] = (float*)arg->{{ input.name }};
{%- elif input.ctx_type == "node" %}
{# Pointer casting #}
    kernel_arg[{{ loop.index0 }}] = (float*)&arg->{{ input.name }};
{%- endif %}

{% endfor %}

    // Marshal outputs to CasADi format
    {{ float_type }}* kernel_res[{{ function_name }}_SZ_RES];
{% for output in outputs | selectattr('ctx_type', 'ne', 'none') %}
{%- if output.ctx_type == "leaf" %}
    kernel_res[{{ loop.index0 }}] = {% if output.is_addr %}&{% endif %}res->{{ output.name }};
{%- elif output.ctx_type == "list" %}
    {# Pointer casting - array decays to pointer #}
    kernel_res[{{ loop.index0 }}] = (float*)res->{{ output.name }};
{%- elif output.ctx_type == "node" %}
    {# Pointer casting #}
    kernel_res[{{ loop.index0 }}] = (float*)&res->{{ output.name }};
{%- endif %}

{% endfor %}

    // Call kernel function
    return {{ function_name }}(kernel_arg, kernel_res, work->iw, work->w, 0);
}