#ifndef REPTESTER_H
#define REPTESTER_H

#include "aliases.h"

struct reptest_params {
  const char *filename;
  char *buffer;
  u64 read_size;
  u64 read_count;
};

struct reptest_results {
  u64 bytes_read;
  u64 read_time;
  u64 page_faults;
};

struct time_stats {
  u64 min_time;
  u64 max_time;
  u64 avg_time;
  u64 total_time;
};

struct mem_stats {
  u64 min_faults;
  u64 max_faults;
  u64 avg_faults;
  u64 total_bytes;
  u64 total_faults;
};

struct reptester {
  reptest_params params;

  const u64 cpu_freq;

  f64 wait_time_secs;
  f64 test_time_secs;
  u64 test_start_time;

  u64 current_run;
  time_stats tstats;
  mem_stats mstats;

  reptest_results results;
};

enum alloc_type {
  ALLOC_TYPE_WITHOUT_MALLOC,
  ALLOC_TYPE_WITH_MALLOC,

  COUNT_ALLOC_TYPE,
};

typedef void (*reptest_func)(reptester *tester, alloc_type type);

struct func_data {
  const char *names[COUNT_ALLOC_TYPE];
  reptest_func func;
};

void handle_alloc(reptester *tester, alloc_type type);
void handle_free(reptester *tester, alloc_type type);
void run_func_test(reptester *tester, reptest_func func, const char *func_name,
                   alloc_type type);
u64 page_fault_count();
void print_results(reptester *tester, const char *name);

#endif // !REPTESTER_H