#include <string.h>

#include "bio/bio_opcode.h"

typedef struct bio_opcode_name_entry {
    const char *name;
    bio_opcode opcode;
} bio_opcode_name_entry;

static const bio_opcode_name_entry k_opcode_names[BIO_OPCODE_COUNT] = {
    {"ABSORB_GGUF", BIO_OPCODE_ABSORB_GGUF},
    {"MANIFOLD_ADDR", BIO_OPCODE_MANIFOLD_ADDR},
    {"PULSE", BIO_OPCODE_PULSE},
    {"PRUNE", BIO_OPCODE_PRUNE},
    {"ZPM_SKIP", BIO_OPCODE_ZPM_SKIP},
    {"OMEGA_ROUTE", BIO_OPCODE_OMEGA_ROUTE},
    {"LEARN_CYCLE", BIO_OPCODE_LEARN_CYCLE},
    {"INFER_CHAT", BIO_OPCODE_INFER_CHAT},
    {"DELTA_COMMIT", BIO_OPCODE_DELTA_COMMIT},
    {"CACHE_BIND", BIO_OPCODE_CACHE_BIND},
    {"SYNC_FENCE", BIO_OPCODE_SYNC_FENCE},
    {"HALT", BIO_OPCODE_HALT},
};

const char *bio_opcode_name(bio_opcode opcode) {
    if ((unsigned)opcode >= (unsigned)BIO_OPCODE_COUNT) {
        return "UNKNOWN";
    }
    return k_opcode_names[(unsigned)opcode].name;
}

int bio_opcode_from_token(const char *token, bio_opcode *opcode_out) {
    if (token == NULL || opcode_out == NULL) {
        return 0;
    }
    for (size_t i = 0; i < (size_t)BIO_OPCODE_COUNT; ++i) {
        if (strcmp(token, k_opcode_names[i].name) == 0) {
            *opcode_out = k_opcode_names[i].opcode;
            return 1;
        }
    }
    return 0;
}
