#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "bio_internal.h"
#include "bio_bdl.h"
#include "bio_forward.h"

static bio_v1_status log_stub_event(bio_context *ctx, const char *opcode,
                                    const bio_operands *ops) {
    FILE *sink = (ctx != NULL && ctx->event_sink != NULL) ? ctx->event_sink : stdout;
    if (ctx == NULL || opcode == NULL || ops == NULL) {
        return BIO_ERR_ARGS;
    }

    fprintf(sink, "bio:event line=%u opcode=%s operands=%u", ops->line, opcode,
            ops->count);
    for (uint32_t i = 0; i < ops->count; ++i) {
        fprintf(sink, " %s=%s", ops->pairs[i].key, ops->pairs[i].value);
    }
    fputc('\n', sink);
    ctx->dispatched_ops += 1u;
    return BIO_OK;
}

static uint64_t parse_u64_default(const char *s, uint64_t fallback) {
    char *end = NULL;
    unsigned long long v = 0;
    if (s == NULL || *s == '\0') {
        return fallback;
    }
    v = strtoull(s, &end, 10);
    if (end == s || *end != '\0') {
        return fallback;
    }
    return (uint64_t)v;
}

static uint32_t parse_u32_default(const char *s, uint32_t fallback) {
    const uint64_t v = parse_u64_default(s, fallback);
    return v > 0xffffffffull ? fallback : (uint32_t)v;
}

static uint8_t parse_threshold_default(const char *s, uint8_t fallback) {
    const uint64_t v = parse_u64_default(s, fallback);
    return v == 0u || v > 15u ? fallback : (uint8_t)v;
}

static int8_t parse_i8_clamp_default(const char *s, int8_t fallback) {
    char *end = NULL;
    double v = 0.0;
    if (s == NULL || *s == '\0') {
        return fallback;
    }
    v = strtod(s, &end);
    if (end == s) {
        return fallback;
    }
    if (v < 0.0) {
        v = -v;
    }
    if (v < 1.0) {
        return 1;
    }
    if (v > 7.0) {
        return 7;
    }
    return (int8_t)v;
}

static uint64_t fnv1a_text(const char *s) {
    uint64_t x = 1469598103934665603ull;
    if (s == NULL) {
        return x;
    }
    while (*s != '\0') {
        x ^= (uint8_t)*s++;
        x *= 1099511628211ull;
    }
    return x;
}

static const bio_gguf_tensor_span *first_int4_tensor(const bio_context *ctx) {
    if (ctx == NULL || !ctx->model_loaded) {
        return NULL;
    }
    for (uint32_t i = 0; i < ctx->model.registered_tensor_count; ++i) {
        if (ctx->model.tensors[i].int4_compatible != 0u) {
            return &ctx->model.tensors[i];
        }
    }
    return NULL;
}

static const uint8_t *active_input_bytes(const bio_context *ctx, size_t *byte_count_out) {
    const bio_gguf_tensor_span *tensor = first_int4_tensor(ctx);
    if (byte_count_out == NULL) {
        return NULL;
    }
    if (tensor != NULL && tensor->data != NULL && tensor->byte_size != 0u) {
        *byte_count_out = tensor->byte_size < BIO_PULSE_SCRATCH_BYTES
                              ? (size_t)tensor->byte_size
                              : (size_t)BIO_PULSE_SCRATCH_BYTES;
        return tensor->data;
    }
    *byte_count_out = 0u;
    return NULL;
}

static void ensure_synthetic_input(uint8_t *out, size_t byte_count) {
    for (size_t i = 0; i < byte_count; ++i) {
        out[i] = (uint8_t)((i % 7u) == 0u ? 0u : (uint8_t)(0x11u + (i & 0x03u)));
    }
}

static void learn_step_delta(bio_context *ctx, size_t byte_count) {
    const size_t n = byte_count < BIO_DELTA_LATTICE_BYTES ? byte_count : BIO_DELTA_LATTICE_BYTES;
    const int8_t clamp = ctx->learn.clamp == 0 ? 1 : ctx->learn.clamp;
    const size_t block_bytes =
        ctx->masks.block_bytes == 0u ? BIO_ROUTE_DEFAULT_BLOCK_BYTES : ctx->masks.block_bytes;
    for (size_t i = 0; i < n; ++i) {
        const size_t block = i / block_bytes;
        if (ctx->masks.block_count != 0u &&
            (block >= ctx->masks.block_count || ctx->masks.omega_active[block] == 0u ||
             ctx->masks.zpm_skip[block] != 0u)) {
            continue;
        }
        if ((ctx->pulse_state[i] & 0x0fu) != 0u && ctx->learn.delta[i] < clamp) {
            ctx->learn.delta[i] += 1;
        }
    }
    ctx->learn.steps += 1u;
}

bio_v1_status bio_op_absorb_gguf(bio_context *ctx, const bio_operands *ops) {
    FILE *sink = (ctx != NULL && ctx->event_sink != NULL) ? ctx->event_sink : stdout;
    const char *path = bio_operand_value(ops, "path");
    bio_v1_status rc = BIO_OK;
    if (ctx == NULL || ops == NULL || path == NULL || *path == '\0') {
        return BIO_ERR_ARGS;
    }
    if (ctx->model_loaded) {
        bio_gguf_close(&ctx->model);
        ctx->model_loaded = false;
    }
    rc = bio_gguf_open(path, &ctx->model);
    if (rc != BIO_OK) {
        fprintf(stderr, "bio: ABSORB_GGUF failed path=%s rc=%d\n", path, (int)rc);
        return rc;
    }
    ctx->model_loaded = true;
    fprintf(sink,
            "bio:event line=%u opcode=ABSORB_GGUF path=%s version=%u tensors=%llu "
            "metadata=%llu alignment=%u registered=%u arch=%s ctx=%u emb=%u layers=%u vocab=%u\n",
            ops->line, path, ctx->model.version,
            (unsigned long long)ctx->model.tensor_count,
            (unsigned long long)ctx->model.metadata_count, ctx->model.alignment,
            ctx->model.registered_tensor_count,
            ctx->model.architecture[0] == '\0' ? "unknown" : ctx->model.architecture,
            ctx->model.context_length, ctx->model.embedding_length, ctx->model.block_count,
            ctx->model.vocab_size);
    for (uint32_t i = 0; i < ctx->model.registered_tensor_count && i < 4u; ++i) {
        const bio_gguf_tensor_span *t = &ctx->model.tensors[i];
        fprintf(sink,
                "bio:tensor index=%u name=%s type=%u dims=%u bytes=%llu "
                "file_offset=%llu int4=%u\n",
                i, t->name, t->ggml_type, t->dims_count,
                (unsigned long long)t->byte_size,
                (unsigned long long)t->file_offset, (unsigned)t->int4_compatible);
    }
    ctx->dispatched_ops += 1u;
    return BIO_OK;
}

bio_v1_status bio_op_manifold_addr(bio_context *ctx, const bio_operands *ops) {
    return log_stub_event(ctx, "MANIFOLD_ADDR", ops);
}

bio_v1_status bio_op_pulse(bio_context *ctx, const bio_operands *ops) {
    FILE *sink = (ctx != NULL && ctx->event_sink != NULL) ? ctx->event_sink : stdout;
    const uint8_t threshold = parse_threshold_default(bio_operand_value(ops, "threshold"), 8u);
    uint64_t executed = 0;
    uint64_t baseline = 0;
    size_t byte_count = 0;
    const uint8_t *input = active_input_bytes(ctx, &byte_count);
    bio_v1_status rc = BIO_OK;
    if (ctx == NULL || ops == NULL) {
        return BIO_ERR_ARGS;
    }
    if (input == NULL) {
        byte_count = 256u;
        ensure_synthetic_input(ctx->pulse_state, byte_count);
        input = ctx->pulse_state;
    }
    if (!ctx->pulse_initialized) {
        memset(ctx->pulse_state, 0, byte_count);
        ctx->pulse_initialized = 1u;
    }
    if (ctx->masks.block_count == 0u) {
        bio_sparse_masks_reset(&ctx->masks, byte_count, BIO_ROUTE_DEFAULT_BLOCK_BYTES);
    }
    rc = g_bio_kernels.pulse_int4(ctx->pulse_state, input, &ctx->masks, byte_count,
                                  threshold, &executed, &baseline);
    if (rc != BIO_OK) {
        return rc;
    }
    ctx->masks.executed_updates = executed;
    ctx->masks.baseline_updates = baseline;
    fprintf(sink,
            "bio:event line=%u opcode=PULSE variant=%s bytes=%llu threshold=%u "
            "executed=%llu baseline=%llu active_blocks=%llu skipped_blocks=%llu\n",
            ops->line, g_bio_kernels.pulse_variant, (unsigned long long)byte_count,
            (unsigned)threshold, (unsigned long long)executed,
            (unsigned long long)baseline, (unsigned long long)ctx->masks.active_blocks,
            (unsigned long long)ctx->masks.skipped_blocks);
    ctx->dispatched_ops += 1u;
    return BIO_OK;
}

bio_v1_status bio_op_prune(bio_context *ctx, const bio_operands *ops) {
    FILE *sink = (ctx != NULL && ctx->event_sink != NULL) ? ctx->event_sink : stdout;
    if (ctx == NULL || ops == NULL) {
        return BIO_ERR_ARGS;
    }
    bio_sparse_prune(&ctx->masks);
    fprintf(sink, "bio:event line=%u opcode=PRUNE active_blocks=%llu skipped_blocks=%llu\n",
            ops->line, (unsigned long long)ctx->masks.active_blocks,
            (unsigned long long)ctx->masks.skipped_blocks);
    ctx->dispatched_ops += 1u;
    return BIO_OK;
}

bio_v1_status bio_op_zpm_skip(bio_context *ctx, const bio_operands *ops) {
    FILE *sink = (ctx != NULL && ctx->event_sink != NULL) ? ctx->event_sink : stdout;
    const size_t block_bytes =
        (size_t)parse_u64_default(bio_operand_value(ops, "block"),
                                  BIO_ROUTE_DEFAULT_BLOCK_BYTES);
    const uint64_t zero_threshold =
        parse_u64_default(bio_operand_value(ops, "zero_threshold"), 0u);
    uint8_t synthetic[BIO_ROUTE_DEFAULT_BLOCK_BYTES * 8u];
    size_t byte_count = 0;
    const uint8_t *input = active_input_bytes(ctx, &byte_count);
    if (ctx == NULL || ops == NULL) {
        return BIO_ERR_ARGS;
    }
    if (input == NULL) {
        byte_count = sizeof(synthetic);
        ensure_synthetic_input(synthetic, byte_count);
        input = synthetic;
    }
    bio_sparse_masks_reset(&ctx->masks, byte_count, block_bytes);
    bio_sparse_zpm_build(&ctx->masks, input, byte_count, zero_threshold);
    fprintf(sink,
            "bio:event line=%u opcode=ZPM_SKIP bytes=%llu blocks=%llu block_bytes=%llu "
            "skipped_blocks=%llu zero_threshold=%llu\n",
            ops->line, (unsigned long long)byte_count,
            (unsigned long long)ctx->masks.block_count,
            (unsigned long long)ctx->masks.block_bytes,
            (unsigned long long)ctx->masks.skipped_blocks,
            (unsigned long long)zero_threshold);
    ctx->dispatched_ops += 1u;
    return BIO_OK;
}

bio_v1_status bio_op_omega_route(bio_context *ctx, const bio_operands *ops) {
    FILE *sink = (ctx != NULL && ctx->event_sink != NULL) ? ctx->event_sink : stdout;
    const uint32_t wake_mod = parse_u32_default(bio_operand_value(ops, "fanout"), 2u);
    const size_t min_active =
        (size_t)parse_u64_default(bio_operand_value(ops, "topk"), 1u);
    uint8_t synthetic[BIO_ROUTE_DEFAULT_BLOCK_BYTES * 8u];
    size_t byte_count = 0;
    const uint8_t *input = active_input_bytes(ctx, &byte_count);
    if (ctx == NULL || ops == NULL) {
        return BIO_ERR_ARGS;
    }
    if (input == NULL) {
        byte_count = sizeof(synthetic);
        ensure_synthetic_input(synthetic, byte_count);
        input = synthetic;
    }
    if (ctx->masks.block_count == 0u) {
        bio_sparse_masks_reset(&ctx->masks, byte_count, BIO_ROUTE_DEFAULT_BLOCK_BYTES);
    }
    bio_sparse_omega_build(&ctx->masks, input, byte_count, wake_mod, min_active);
    fprintf(sink,
            "bio:event line=%u opcode=OMEGA_ROUTE blocks=%llu active_blocks=%llu "
            "wake_mod=%u min_active=%llu\n",
            ops->line, (unsigned long long)ctx->masks.block_count,
            (unsigned long long)ctx->masks.active_blocks, wake_mod,
            (unsigned long long)min_active);
    ctx->dispatched_ops += 1u;
    return BIO_OK;
}

bio_v1_status bio_op_learn_cycle(bio_context *ctx, const bio_operands *ops) {
    FILE *sink = (ctx != NULL && ctx->event_sink != NULL) ? ctx->event_sink : stdout;
    const char *mode = bio_operand_value(ops, "mode");
    const char *persist = bio_operand_value(ops, "persist");
    const int8_t clamp = parse_i8_clamp_default(bio_operand_value(ops, "clamp"), 2);
    size_t byte_count = 0;
    if (ctx == NULL || ops == NULL) {
        return BIO_ERR_ARGS;
    }
    (void)active_input_bytes(ctx, &byte_count);
    if (byte_count == 0u) {
        byte_count = 256u;
    }
    if (mode == NULL || strcmp(mode, "start") == 0) {
        ctx->learn.active = 1u;
        ctx->learn.clamp = clamp;
        if (persist != NULL && *persist != '\0') {
            uint64_t loaded_steps = 0;
            if (bio_bdl_load(persist, ctx->learn.delta, BIO_DELTA_LATTICE_BYTES,
                             &loaded_steps) == BIO_OK) {
                ctx->learn.steps = loaded_steps;
            }
        }
    } else if (strcmp(mode, "step") == 0) {
        if (ctx->learn.active == 0u) {
            ctx->learn.active = 1u;
        }
        ctx->learn.clamp = clamp;
        learn_step_delta(ctx, byte_count);
    } else if (strcmp(mode, "pause") == 0 || strcmp(mode, "stop") == 0) {
        ctx->learn.active = 0u;
    } else if (strcmp(mode, "commit") == 0) {
        ctx->learn.committed_dry_runs += 1u;
    } else {
        return BIO_ERR_OPERAND;
    }
    fprintf(sink,
            "bio:event line=%u opcode=LEARN_CYCLE mode=%s active=%u steps=%llu "
            "clamp=%d delta_bytes=%u\n",
            ops->line, mode == NULL ? "start" : mode, (unsigned)ctx->learn.active,
            (unsigned long long)ctx->learn.steps, (int)ctx->learn.clamp,
            (unsigned)BIO_DELTA_LATTICE_BYTES);
    ctx->dispatched_ops += 1u;
    return BIO_OK;
}

bio_v1_status bio_op_infer_chat(bio_context *ctx, const bio_operands *ops) {
    FILE *sink = (ctx != NULL && ctx->event_sink != NULL) ? ctx->event_sink : stdout;
    const char *prompt = bio_operand_value(ops, "prompt");
    uint64_t requested_tokens = parse_u64_default(bio_operand_value(ops, "max_tokens"), 16u);
    uint32_t prompt_tokens[BIO_CHAT_MAX_TOKENS];
    uint32_t prompt_token_count = 0;
    size_t byte_count = 0;
    const uint8_t *input = active_input_bytes(ctx, &byte_count);
    if (ctx == NULL || ops == NULL) {
        return BIO_ERR_ARGS;
    }
    if (requested_tokens > BIO_CHAT_MAX_TOKENS) {
        requested_tokens = BIO_CHAT_MAX_TOKENS;
    }
    if (input == NULL) {
        byte_count = 256u;
        ensure_synthetic_input(ctx->pulse_state, byte_count);
        input = ctx->pulse_state;
    }
    if (!ctx->pulse_initialized) {
        memset(ctx->pulse_state, 0, byte_count);
        ctx->pulse_initialized = 1u;
    }
    if (ctx->masks.block_count == 0u) {
        bio_sparse_masks_reset(&ctx->masks, byte_count, BIO_ROUTE_DEFAULT_BLOCK_BYTES);
    }
    ctx->chat.prompt_hash = fnv1a_text(prompt);
    prompt_token_count = bio_tokenize_bytes(prompt == NULL ? "" : prompt, prompt_tokens,
                                            BIO_CHAT_MAX_TOKENS);
    if (prompt_token_count == 0u) {
        prompt_tokens[prompt_token_count++] = 0u;
    }
    fprintf(sink,
            "bio:event line=%u opcode=INFER_CHAT native_loop=1 prompt_hash=%llu "
            "max_tokens=%llu prompt_tokens=%u route_blocks=%llu\n",
            ops->line, (unsigned long long)ctx->chat.prompt_hash,
            (unsigned long long)requested_tokens, prompt_token_count,
            (unsigned long long)ctx->masks.block_count);
    for (uint64_t t = 0; t < requested_tokens; ++t) {
        uint64_t executed = 0;
        uint64_t baseline = 0;
        bio_forward_result forward;
        const uint32_t wake_mod = (uint32_t)((ctx->chat.prompt_hash + t) % 7u) + 1u;
        bio_sparse_omega_build(&ctx->masks, input, byte_count, wake_mod, 1u);
        if (g_bio_kernels.pulse_int4(ctx->pulse_state, input, &ctx->masks, byte_count, 8u,
                                     &executed, &baseline) != BIO_OK) {
            return BIO_ERR_INTERNAL;
        }
        if (ctx->learn.active != 0u) {
            learn_step_delta(ctx, byte_count);
        }
        if (ctx->model_loaded &&
            bio_forward_next_token(&ctx->model, prompt_tokens, prompt_token_count,
                                   ctx->chat.prompt_hash + t, &forward) == BIO_OK) {
            ctx->chat.last_token = forward.token;
            executed += forward.executed_ops;
            baseline += forward.baseline_ops;
        } else {
            ctx->chat.last_token =
                (uint32_t)((ctx->chat.prompt_hash ^ executed ^ (t * 1315423911ull)) & 0xffu);
        }
        if (prompt_token_count < BIO_CHAT_MAX_TOKENS) {
            prompt_tokens[prompt_token_count++] = ctx->chat.last_token;
        }
        ctx->chat.generated_tokens += 1u;
        if (ctx->arenas.kv_used + sizeof(ctx->chat.last_token) <= BIO_KV_CACHE_BYTES) {
            memcpy(ctx->arenas.kv + ctx->arenas.kv_used, &ctx->chat.last_token,
                   sizeof(ctx->chat.last_token));
            ctx->arenas.kv_used += sizeof(ctx->chat.last_token);
        }
        fprintf(sink,
                "bio:chat token_index=%llu token=%u text=\"%c\" executed=%llu baseline=%llu "
                "active_blocks=%llu\n",
                (unsigned long long)t, ctx->chat.last_token,
                (ctx->chat.last_token >= 32u && ctx->chat.last_token < 127u)
                    ? (char)ctx->chat.last_token
                    : '.',
                (unsigned long long)executed, (unsigned long long)baseline,
                (unsigned long long)ctx->masks.active_blocks);
    }
    ctx->dispatched_ops += 1u;
    return BIO_OK;
}

bio_v1_status bio_op_delta_commit(bio_context *ctx, const bio_operands *ops) {
    FILE *sink = (ctx != NULL && ctx->event_sink != NULL) ? ctx->event_sink : stdout;
    const char *mode = bio_operand_value(ops, "mode");
    const char *target = bio_operand_value(ops, "target");
    uint64_t nonzero = 0;
    bio_v1_status persist_rc = BIO_OK;
    if (ctx == NULL || ops == NULL) {
        return BIO_ERR_ARGS;
    }
    for (size_t i = 0; i < BIO_DELTA_LATTICE_BYTES; ++i) {
        nonzero += ctx->learn.delta[i] != 0 ? 1u : 0u;
    }
    ctx->learn.committed_dry_runs += 1u;
    if (mode != NULL && strcmp(mode, "persist") == 0 && target != NULL && *target != '\0') {
        persist_rc = bio_bdl_save(target, ctx->learn.delta, BIO_DELTA_LATTICE_BYTES,
                                  ctx->learn.steps);
        if (persist_rc != BIO_OK) {
            return persist_rc;
        }
    }
    fprintf(sink,
            "bio:event line=%u opcode=DELTA_COMMIT mode=%s "
            "nonzero_delta_bytes=%llu commits=%llu checksum=%llu\n",
            ops->line, mode == NULL ? "sidecar_dry_run" : mode, (unsigned long long)nonzero,
            (unsigned long long)ctx->learn.committed_dry_runs,
            (unsigned long long)bio_bdl_checksum(ctx->learn.delta, BIO_DELTA_LATTICE_BYTES));
    ctx->dispatched_ops += 1u;
    return BIO_OK;
}

bio_v1_status bio_op_cache_bind(bio_context *ctx, const bio_operands *ops) {
    FILE *sink = (ctx != NULL && ctx->event_sink != NULL) ? ctx->event_sink : stdout;
    const char *arena = bio_operand_value(ops, "arena");
    const uint64_t requested = parse_u64_default(bio_operand_value(ops, "bytes"), 0u);
    if (ctx == NULL || ops == NULL || arena == NULL) {
        return BIO_ERR_ARGS;
    }
    if (strcmp(arena, "kv") == 0) {
        ctx->arenas.requested_kv_bytes = requested;
    } else if (strcmp(arena, "route") == 0) {
        ctx->arenas.requested_route_bytes = requested;
    } else if (strcmp(arena, "delta") == 0) {
        ctx->arenas.requested_delta_bytes = requested;
    }
    fprintf(sink,
            "bio:event line=%u opcode=CACHE_BIND arena=%s native_bound=1 "
            "kv_capacity=%u delta_capacity=%u\n",
            ops->line, arena, (unsigned)BIO_KV_CACHE_BYTES,
            (unsigned)BIO_DELTA_LATTICE_BYTES);
    ctx->dispatched_ops += 1u;
    return BIO_OK;
}

bio_v1_status bio_op_sync_fence(bio_context *ctx, const bio_operands *ops) {
    FILE *sink = (ctx != NULL && ctx->event_sink != NULL) ? ctx->event_sink : stdout;
    if (ctx == NULL || ops == NULL) {
        return BIO_ERR_ARGS;
    }
#if defined(_MSC_VER)
    _ReadWriteBarrier();
#elif defined(__GNUC__) || defined(__clang__)
    __sync_synchronize();
#endif
    fprintf(sink, "bio:event line=%u opcode=SYNC_FENCE scope=native learn_steps=%llu\n",
            ops->line, (unsigned long long)ctx->learn.steps);
    ctx->dispatched_ops += 1u;
    return BIO_OK;
}

bio_v1_status bio_op_halt(bio_context *ctx, const bio_operands *ops) {
    const bio_v1_status rc = log_stub_event(ctx, "HALT", ops);
    if (ctx != NULL) {
        ctx->halted = true;
    }
    return rc;
}
