#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
#include <string>

std::vector<int> data = {10, 6, 3, 8, 2, 5};
std::vector<float> test = {10, 8, 4.5, 5.5, 5, 3.5};
std::vector<float> result;

const int avg = 2; // rolling average of two

/* Use a queue to keep the history and another integer for current sum */
/* Check the queue size before use. */
void rolling_avg(int &next) {
    static int sum = 0;
    static std::queue<int> pool;

    if(pool.size() != avg) {
        // pool is not full yet. Add to sum and push in queue.
        sum += next;
        pool.push(next);
    } else {
        // pool is full. Remove the first from sum and add the next data.
        sum -= pool.front();
        pool.pop();

        sum += next;
        pool.push(next);
    }

    result.push_back((float)sum / pool.size());
}


void read_dat_and_process(const std::string &filepath) {
    std::cout << "reading file: " << filepath << std::endl;

    // Read line by line and get the second token.
    // Ignore some data cleaning in this method for demo only.
    // And ignore proper error handling.
    std::ifstream infile(filepath);
    int line_num = 0, num = 0;

    std::cout << "...start processing" << std::endl;
    while(infile >> line_num >> num) {
        std::cout << line_num << " " << num << std::endl;
        /* for every num, run the rolling_avg function to populate the result vector.*/
        rolling_avg(num);
    }
    std::cout << "...end of file" << std::endl;

    infile.close();
}

int main() {

    read_dat_and_process("read_avg_test.dat");

    std::cout << "result: ";
    for(auto num : result)
        std::cout << num << " ";
    std::cout << std::endl;


    /* Sample code for using the method: rolling_avg */

    // for(auto num : data)
    //     rolling_avg(num);

    // std::cout << "data:   ";
    // for(auto num : data)
    //     std::cout << num << " ";
    // std::cout << std::endl;

    // std::cout << "test:   ";
    // for(auto num : test)
    //     std::cout << num << " ";
    // std::cout << std::endl;

    // std::cout << "result: ";
    // for(auto num : result)
    //     std::cout << num << " ";
    // std::cout << std::endl;
    
    return 0;
}