#ifndef PROTOTYPE1_SRC_L1_5_CODEGEN_TRAIT_BOX_AND_REF_H
#define PROTOTYPE1_SRC_L1_5_CODEGEN_TRAIT_BOX_AND_REF_H

#include "../../l1/codegen/codegen.h"

typedef struct {
    SpanU8 type;
    SpanU8 name;
} NamedVariableRecordRef;

#include "../../../gen/l1/eve/embassy_l1_5/SpanNamedVariableRecordRef.h"

typedef struct {
    SpanNamedVariableRecordRef params;
    SpanU8 return_type;
    SpanU8 name;
} NamedMethodSignatureRecordRef;

#include "../../../gen/l1/eve/embassy_l1_5/SpanNamedMethodSignatureRecordRef.h"

typedef struct {
    SpanNamedMethodSignatureRecordRef methods;
    SpanU8 name;
} NamedTraitDefRecordRef;

NODISCARD VecU8 generate_trait_table_structure(NamedTraitDefRecordRef trait){
    VecU8 res = VecU8_from_cstr("typedef struct {");
    // todo: add iteration macro
    for (size_t i = 0; i < trait.methods.len; i++) {
        NamedMethodSignatureRecordRef method = *SpanNamedMethodSignatureRecordRef_at(trait.methods, i);
        VecU8_append_vec(&res, VecU8_fmt(SPACE "%s (*%s)(", method.return_type, method.name));
        for (size_t p = 0; p < method.params.len; p++) {
            NamedVariableRecordRef param = *SpanNamedVariableRecordRef_at(method.params, p);
            if (p)
                VecU8_append_span(&res, cstr(", "));
            VecU8_append_span(&res, param.type);
        }
        VecU8_append_span(&res, cstr(");\n"));
    }
    VecU8_append_vec(&res, VecU8_fmt("} %s;\n\n", trait.name));
    return res;
}

typedef struct {
    NamedTraitDefRecordRef trait;
    bool box;
    bool ref;
    bool mut_ref;
} trait_wrapper_boil_options;

NODISCARD VecU8 generate_trait_wrapper_boilerplate(trait_wrapper_boil_options op) {
    VecU8 res = VecU8_new();
    // todo: write it
    return res;
}

#endif