#include <assert.h>
#include <driver.h>
#include <string.h>
#include <stdbool.h>
#include <mono/metadata/object.h>
#include <mono/metadata/exception.h>
#include <mono/metadata/appdomain.h>

extern void _start(void);

MonoMethod* lookup_interop_method(const char* method_name)
{
    MonoMethod* method = NULL;
    method = lookup_dotnet_method("PixiEditor.Extensions.Sdk.dll", "PixiEditor.Extensions.Sdk.Bridge", "Native", method_name, -1);
    assert(method);

    return method;
}

void invoke_interop_method(MonoMethod* method, void* params)
{
    MonoObject* exception = NULL;
    MonoObject* res = mono_runtime_invoke(method, NULL, params, &exception);
    if(exception != NULL)
    {
        mono_print_unhandled_exception(exception);
    }

    free(exception);
    free(method);
}

// Content is autogenerated
void attach_imported_functions(){}

void attach_internal_calls()
{
    attach_imported_functions();
}

void initialize_runtime(void)
{
    static int runtime_initialized = 0;

    if (runtime_initialized == 0) {
        _start();
        attach_internal_calls();
        runtime_initialized = 1;
    }
}

__attribute((export_name("load")))
void load()
{
    initialize_runtime();

    MonoMethod* metod = lookup_interop_method("Load");
    invoke_interop_method(metod, NULL);
}

__attribute((export_name("initialize")))
void initialize()
{
    MonoMethod* metod = lookup_interop_method("Initialize");
    invoke_interop_method(metod, NULL);
}