#include "call/zval_array_to_zval.h"

#include "php_embed_runtime.h"

static zval *
valaphp_embed_params_from_php_zval_array(Phpzval *args, uint32_t *param_count)
{
    uint32_t count = 0;
    if (args != NULL)
        count = (uint32_t) php_zval_count(args);

    *param_count = count;
    if (count == 0)
        return NULL;

    zval *params = g_new0(zval, count);
    for (uint32_t i = 0; i < count; i++) {
        Phpzval *child = php_zval_get_index(args, (int) i);
        valaphp_embed_zval_to_zend_zval(child, &params[i]);
        if (child != NULL)
            php_zval_unref(child);
    }

    return params;
}

static void
valaphp_embed_params_free(zval *params, uint32_t param_count)
{
    if (params == NULL)
        return;

    for (uint32_t i = 0; i < param_count; i++)
        zval_ptr_dtor(&params[i]);
    g_free(params);
}

Phpzval *
valaphp_embed_call_zval_array_to_zval(const char *function_name, Phpzval *args, char **error_message)
{
    if (!valaphp_embed_ensure_initialized(error_message))
        return NULL;

    uint32_t param_count = 0;
    zval *params = valaphp_embed_params_from_php_zval_array(args, &param_count);
    zval return_value;

    if (!valaphp_embed_call_php_function(function_name, params, param_count, &return_value, error_message)) {
        valaphp_embed_params_free(params, param_count);
        return NULL;
    }

    Phpzval *result = valaphp_embed_zend_zval_to_php_zval(&return_value);
    zval_ptr_dtor(&return_value);
    valaphp_embed_params_free(params, param_count);
    return result;
}

char *
valaphp_embed_call_zval_array_output_to_string(const char *function_name, Phpzval *args, char **error_message)
{
    if (!valaphp_embed_ensure_initialized(error_message))
        return NULL;

    uint32_t param_count = 0;
    zval *params = valaphp_embed_params_from_php_zval_array(args, &param_count);
    char *result = valaphp_embed_call_php_function_output_to_string(function_name, params, param_count, error_message);
    valaphp_embed_params_free(params, param_count);
    return result;
}
