#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "csim.h"

#define NUM_CLIENTS 5
#define DB_SIZE 500
#define DATA_ITEM_SIZE 1024
#define BANDWIDTH 10000
#define CACHE_SIZE 100
#define NUM_HOT_ITEMS 50
#define SIMULATION_TIME 10e4

double t_query_arr[] = {5, 10, 25, 50, 100};
double t_update_arr[] = {5, 10, 20, 100, 200};
float hot_access_prob = 0.8;
float hot_update_prob = 0.33;

typedef struct {
int id;
int cache[CACHE_SIZE];
int cache_age[CACHE_SIZE]; // Add this field to store age of each item
double q_gen_time;
double u_arr_time;
} node;


FACILITY server;
TABLE query_delay, cache_hit_ratio;
node *nodes;
float total_queries = 0;
float cache_hits = 0;

void client();
void generate_query(node *n);
void query_result(node *n);
int is_item_in_cache(node *n, int item);


void update_cache(node *n, int data_item) {
int min_age_index = 0;

for (int i = 0; i < CACHE_SIZE; i++) {
if (n->cache[i] == -1) { // Empty cache slot found
n->cache[i] = data_item;
n->cache_age[i] = 1;
return;
}

if (n->cache_age[i] < n->cache_age[min_age_index]) {
min_age_index = i;
}
}

// Replace the least recently used item in the cache
n->cache[min_age_index] = data_item;
n->cache_age[min_age_index] = 1;
}


int main() {
long err;
create("simple_pull_based_cache");
nodes = (node *)malloc(NUM_CLIENTS * sizeof(node));
err = facility("Server", &server);
handle_csim_error_message(err);
table_init("Query Delay", &query_delay);
table_init("Cache Hit Ratio", &cache_hit_ratio);

// Simulating
for (size_t q = 0; q < sizeof(t_query_arr) / sizeof(t_query_arr[0]); q++) {
for (size_t u = 0; u < sizeof(t_update_arr) / sizeof(t_update_arr[0]); u++) {
reset();

total_queries = 0;
cache_hits = 0;

for (int i = 0; i < NUM_CLIENTS; i++) {
nodes[i].id = i;
nodes[i].q_gen_time = t_query_arr[q];
nodes[i].u_arr_time = t_update_arr[u];
// Initialize cache

for (int j = 0; j < CACHE_SIZE; j++) {
nodes[i].cache[j] = -1;
nodes[i].cache_age[j] = -1; // Initialize age of each item to -1
}
node_activity(client);
}

schedule(START, 0.0);
schedule(END, SIMULATION_TIME);
simulate();

printf("Cache hit ratio: %.2f\n", cache_hits / total_queries);
printf("Query delay: %.2f\n", tbl_mean(query_delay));
printf("\n");
}
}

// Clean up
table_rm(query_delay);
table_rm(cache_hit_ratio);
err = facility_rm(server);
handle_csim_error_message(err);
cleanup();
free(nodes);

return 0;
}

void client() {
node *n = nodes[node_id()];
while (clock < SIMULATION_TIME) {
hold(exponential(n->q_gen_time));

float prob = lrand48() / (float)RAND_MAX;

// Hot data item or cold data item
int data_item;
if (prob < hot_access_prob) {
data_item = lrand48() % NUM_HOT_ITEMS + 1;
} else {
data_item = NUM_HOT_ITEMS + (lrand48() % (DB_SIZE - NUM_HOT_ITEMS));
}

generate_query(n);
}
}

void generate_query(node *n) {
request(server);
double q_start_time = clock;
hold(DATA_ITEM_SIZE * 8 / BANDWIDTH);
int cache_hit = is_item_in_cache(n, data_item);

if (cache_hit) {
cache_hits++;
release(server);

// Send a check message to the server
request(server);
hold(DATA_ITEM_SIZE * 8 / BANDWIDTH);

// Receive confirm message from the server
release(server);

} else {
// Request data item from the server
release(server);
query_result(n);
}

// Calculate query delay
double q_delay = clock - q_start_time;
sample(query_delay, q_delay);

total_queries++;
}


void query_result(node *n) {
hold(exponential(n->u_arr_time));

// Probability of hot data item update
float prob = lrand48() / (float)RAND_MAX;

if (prob < hot_update_prob) {
request(server);
hold(DATA_ITEM_SIZE * 8 / BANDWIDTH);

// Update hot data item
release(server);
}

// Update the cache based on the LRU policy
update_cache(n, data_item);
}
int is_item_in_cache(node *n, int item) {
int item_found = 0;
for (int i = 0; i < CACHE_SIZE; i++) {
if (n->cache[i] == item) {
n->cache_age[i] = 1;
item_found = 1;
} else {
n->cache_age[i]++;
}
}
return item_found;
}
void handle_csim_error_message(long err) {
if (err != 0) {
printf("Error: %s\n", csim_error_message[err]);
exit(1);
}
}
fix the errors in this code, i think its for a different csim library, im using csim20 and compiling using csim64.gcc

code.c: In function ‘update_cache’:
code.c:43:1: error: ‘for’ loop initial declarations are only allowed in C99 or C11 mode
 for (int i = 0; i < CACHE_SIZE; i++) {
 ^
code.c:43:1: note: use option -std=c99, -std=gnu99, -std=c11 or -std=gnu11 to compile your code
code.c: In function ‘main’:
code.c:65:33: error: macro "facility" passed 2 arguments, but takes just 1
 err = facility("Server", &server);
                                 ^
code.c:65:7: error: ‘facility’ undeclared (first use in this function)
 err = facility("Server", &server);
       ^
code.c:65:7: note: each undeclared identifier is reported only once for each function it appears in
code.c:71:1: error: ‘for’ loop initial declarations are only allowed in C99 or C11 mode
 for (size_t q = 0; q < sizeof(t_query_arr) / sizeof(t_query_arr[0]); q++) {
 ^
code.c:72:1: error: ‘for’ loop initial declarations are only allowed in C99 or C11 mode
 for (size_t u = 0; u < sizeof(t_update_arr) / sizeof(t_update_arr[0]); u++) {
 ^
code.c:78:1: error: ‘for’ loop initial declarations are only allowed in C99 or C11 mode
 for (int i = 0; i < NUM_CLIENTS; i++) {
 ^
code.c:84:1: error: ‘for’ loop initial declarations are only allowed in C99 or C11 mode
 for (int j = 0; j < CACHE_SIZE; j++) {
 ^
code.c:91:10: error: ‘START’ undeclared (first use in this function)
 schedule(START, 0.0);
          ^
code.c:92:10: error: ‘END’ undeclared (first use in this function)
 schedule(END, SIMULATION_TIME);
          ^
code.c: In function ‘client’:
code.c:113:11: error: incompatible types when initializing type ‘struct node *’ using type ‘node’
 node *n = nodes[node_id()];
           ^
code.c: In function ‘generate_query’:
code.c:135:37: error: ‘data_item’ undeclared (first use in this function)
 int cache_hit = is_item_in_cache(n, data_item);
                                     ^
code.c: In function ‘query_result’:
code.c:177:17: error: ‘data_item’ undeclared (first use in this function)
 update_cache(n, data_item);
                 ^
code.c: In function ‘is_item_in_cache’:
code.c:181:1: error: ‘for’ loop initial declarations are only allowed in C99 or C11 mode
 for (int i = 0; i < CACHE_SIZE; i++) {
 ^
code.c: At top level:
code.c:191:6: warning: conflicting types for ‘handle_csim_error_message’
 void handle_csim_error_message(long err) {
      ^
code.c:66:1: note: previous implicit declaration of ‘handle_csim_error_message’ was here
 handle_csim_error_message(err);
 ^
code.c: In function ‘handle_csim_error_message’:
code.c:193:23: error: ‘csim_error_message’ undeclared (first use in this function)
 printf("Error: %s\n", csim_error_message[err]);


