#include <stdlib.h>
#include "hnsw.h"

HNSWContext *hnsw_init_context(const char *filename, size_t dim, size_t len)
{
    HNSWContext *ctx = (HNSWContext *)malloc(sizeof(HNSWContext));
    ctx->dim = dim;
    ctx->len = len;
    ctx->data = (VecData *)malloc(sizeof(VecData) * len);

    // init file context
    FileContext *f_ctx = init_file_context(filename);

    for (int i = 0; i < len; i++)
    {
        ctx->data[i].id = i;
        ctx->data[i].vec = (float *)malloc(sizeof(float) * GLOBAL_DIM);
        read_vec_data(f_ctx, ctx->data[i].vec);
    }

    free_file_context(f_ctx);
    return ctx;
}

void hnsw_approximate_knn(HNSWContext *ctx, VecData *q, int *results, int k)
{
    // sort existing vectors
    for (size_t i = 0; i < k && i < ctx->len - 1; i++)
    {
        float min_dist = vec_dist(*q, ctx->data[i]);
        size_t idx = i;
        for (size_t j = i + 1; j < ctx->len; j++)
        {
            float dist = vec_dist(*q, ctx->data[j]);
            if (dist < min_dist)
            {
                min_dist = dist;
                idx = j;
            }
        }
        if (idx != i)
        {
            VecData tmp = ctx->data[idx];
            ctx->data[idx] = ctx->data[i];
            ctx->data[i] = tmp;
        }
    }

    // copy results
    for (int i = 0; i < k && i < ctx->len; i++)
    {
        results[i] = ctx->data[i].id;
    }
}
