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

#define K 100

float cal_recall_value(int *results, int *trueset, int k)
{
    int cnt = 0;
    for (int i = 0; i < k; i++)
    {
        int val = results[i];
        for (int j = 0; j < k; j++)
        {
            if (val == trueset[j])
            {
                cnt++;
                break;
            }
        }
    }

    return ((float)cnt) / ((float)k);
}

int main(int argc, char *argv[])
{
    if (argc != 6)
    {
        printf("argc: %d\n", argc);
        printf("./hnsw_test base_file data_size query_file groundtruth_file");
        exit(1);
    }

    int data_size = atoi(argv[2]);
    printf("data size: %d\n", data_size);
    int query_size = atoi(argv[4]);

    // init query and groundtruth files
    FileContext *query_file_ctx = init_file_context(argv[3]);
    FileContext *gt_file_ctx = init_file_context(argv[5]);

    // TODO: report time cost here

    HNSWContext *ctx = hnsw_init_context(argv[1], GLOBAL_DIM, data_size);
    printf("HNSW context initialized!\n");
    VecData q_vec;
    q_vec.vec = (float *)malloc(sizeof(float) * GLOBAL_DIM);
    int q_results[100];
    int true_results[100];
    float total_recall_values = 0.0;
    for (int i = 0; i < query_size; i++)
    {
        read_vec_data(query_file_ctx, q_vec.vec);
        read_id_data(gt_file_ctx, true_results, K);
        hnsw_approximate_knn(ctx, &q_vec, q_results, K);
        total_recall_values += cal_recall_value(q_results, true_results, K);
    }

    // report recall value
    printf("Recall value: %.4f\n", total_recall_values / ((float)query_size));

    free_file_context(query_file_ctx);
    free_file_context(gt_file_ctx);
    return 0;
}
