#include <glib.h>
#include <string.h>
#include <php.h>
#include <Zend/zend.h>
#include <Zend/zend_exceptions.h>

#include <phpef-runtime-core.h>

#include "phpef_runtime_embed_value_conversion.h"

void phpef_runtime_embed_ensure_initialized(void);

static void
phpef_runtime_embed_print_zval(PhpefRuntimeCoreZval *value)
{
    phpef_runtime_embed_ensure_initialized();

    zval zend_value;
    phpef_runtime_embed_phpefzval_to_zendzval(value, &zend_value);

    zend_try {
        zend_print_zval(&zend_value, 0);
    } zend_catch {
        if (EG(exception)) {
            zend_clear_exception();
        }
    } zend_end_try();

    zval_ptr_dtor(&zend_value);
}

void
phpef_runtime_embed_phpfunc_echo(PhpefRuntimeCoreZval *value)
{
    phpef_runtime_embed_print_zval(value);
}

void
phpef_runtime_embed_phpfunc_echo_string(const char *value)
{
    phpef_runtime_embed_ensure_initialized();

    if (value == NULL) {
        return;
    }

    zend_try {
        PHPWRITE(value, strlen(value));
    } zend_catch {
        if (EG(exception)) {
            zend_clear_exception();
        }
    } zend_end_try();
}

PhpefRuntimeCoreZval *
phpef_runtime_embed_phpfunc_print(PhpefRuntimeCoreZval *value)
{
    phpef_runtime_embed_print_zval(value);
    return phpef_runtime_core_zval_from_int(1);
}

gint64
phpef_runtime_embed_phpfunc_print_string(const char *value)
{
    phpef_runtime_embed_phpfunc_echo_string(value);
    return 1;
}
