#include "data_recorder.h"
#include <unistd.h>

int main() {
    // Instantiate the class
    DataRecorder dr;

    printf("Test Reg Read - 0x%x\n", dr.read_reg(UTIL_REG_BASE + 0x0));

    // Setup Timing Engine and data generator to test
    uint32_t n_pulses = 128;
    float inter_cpi = 100e-6;
    // float pri = 75e-6;
    float pri = 100e-6;
    uint32_t n_samples = 16384;
    int test_time_ms = 10000;

    // Set false to just pull data across the pcie and run the data validator.
    // Set true to save data to disk
    bool save_to_disk = false;

    float cpi_time = n_pulses * pri + inter_cpi;
    float cpi_num_bytes = n_pulses * n_samples * 16;

    float expected_data_rate = cpi_num_bytes / cpi_time / 1e6;
    // PCIe Gen3 x16 Theoretical Max is 16GBPS, 
    // 128B/130B encoding drops that to 15753.8 MBPS
    // Assuming an MSP of 128 bytes (84.2% effeciency), that further drops to 13264 MBPS
    // Assuming an MSP of 256 bytes (91.4% effeciency), that further drops to 14399 MBPS
    // Assuming an MSP of 512 bytes (95.5% effeciency), that further drops to 15044 MBPS  <- Threadripper box uses 512
    // Currently achieving 13836 MBPS without errors which is ~92% of 15044 MBPS
    printf("Expected Data Rate - %.2f MBps Per Channel, Total %.2f\n", expected_data_rate, expected_data_rate * NUM_DMA_CH);

    dr.write_reg(TIMING_REG_BASE + 0x0, 1);
    dr.write_reg(TIMING_REG_BASE + 0x4, (uint32_t)(pri * CLK_RATE + 0.5) - 1);
    dr.write_reg(TIMING_REG_BASE + 0x8, n_pulses);
    dr.write_reg(TIMING_REG_BASE + 0x10, inter_cpi * CLK_RATE);

    for (int i = 0; i < 4; i++) {
        printf("Timing Reg 0x%x - 0x%x\n", i*4, dr.read_reg(TIMING_REG_BASE + i*4));
    }

    dr.write_reg(DATA_GEN_REG_BASE, n_samples - 1);

    dr.set_validate_cnt_data(true, dr.read_reg(TIMING_REG_BASE + 0x4) + 1, dr.read_reg(TIMING_REG_BASE + 0x10) + 1, n_pulses);

    // Start listening for data
    dr.start_recording("/media/hptnvme/test.bin", save_to_disk);
    sleep(1);
    // Start the timing engine so data starts flowing
    dr.write_reg(TIMING_REG_BASE + 0x0, 0);
    // Wait a while
    std::this_thread::sleep_for(std::chrono::milliseconds(test_time_ms));
    dr.write_reg(TIMING_REG_BASE + 0x0, 1);
    sleep(2);
    dr.stop_recording();
    

    printf("Expected Data Rate - %.2f MBps Per Channel, Total %.2f\n", expected_data_rate, expected_data_rate * NUM_DMA_CH);


}
