/*
 * Creator: Naman Dixit
 * Notice: © Copyright 2020 Naman Dixit
 */

typedef struct Grunt {
    Char *id;
    Sint memory;
    B32 rejoin_asked;
    Sint time_to_die; // in ms
} Grunt;

typedef struct Grunt_Survey {
    Char **grunt_ids;
    U16 *ports;
    U64 milli_passed;
    U64 milli_last;
    Char *resource_id;
} Grunt_Survey;

typedef struct Grunt_Tracker {
    Grunt *grunts;
    Size *free_list;
    Hash_Table map;
} Grunt_Tracker;

internal_function
void gruntTrackBegin (Grunt_Tracker *t, Grunt g)
{
    if (t->grunts == NULL) {
        t->map = htCreate(0);
        sbufAdd(t->grunts, (Grunt){0}); // SInce 0 index out of hash table will be invalid
    }

    Size insertion_index = 0;

    if (sbufElemin(t->free_list) > 0) {
        t->grunts[t->free_list[0]] = g;
        insertion_index = t->free_list[0];
        sbufUnsortedRemove(t->free_list, 0);
    } else {
        sbufAdd(t->grunts, g);
        insertion_index = sbufElemin(t->grunts) - 1;
    }

    htInsert(&t->map, hashString(g.id), insertion_index);
}

internal_function
void gruntTrackEnd (Grunt_Tracker *t, Char *grunt_id)
{
    U64 hash = hashString(grunt_id);
    Size index = htLookup(&t->map, hash);
    sbufAdd(t->free_list, index);
    free(t->grunts[index].id);
    t->grunts[index] = (Grunt){0};
    htRemove(&t->map, hash);
}
