#include <stdlib.h>
#include <stdio.h>
#include <mpi.h>
#include "main.h"
#include "interval.h"
#include "master.h"
#include "slave.h"

#define LIST_SIZE 1000000    // Total items for all tasks (million)
int test_stride =  1;        // Items per task
int test_current_item = 0;   // Position in item list
double test_list[LIST_SIZE]; // List containing all test items

int main(int argc, char **argv) {
    int role;

    // Create list of zero values.
    for(int i = 0; i < LIST_SIZE; i++)
        test_list[i] = .0;

    // Perhaps the user wants a different stride?
    if( argc == 2 )
        test_stride = atoi(argv[1]);

    // Initialize MPI.
    argc = 1; // Reset argc to hide our arguments.
    MPI_Init(&argc, &argv);

    // Find out my identity in the default communicator.
    MPI_Comm_rank(MPI_COMM_WORLD, &role);

    if(role == 0) {
        int ntasks = master_init();
        printf("Number of tasks: %d\n", ntasks);

        // Benchmark
        double wct, ust, syt;
        interval start_time = interval_init();
        master_run(ntasks, test_stride);
        (void) interval_time(start_time, &wct, &ust, &syt);
        printf("test list has size: %d\n", LIST_SIZE);
        printf("real: %.12e\nuser: %.12e\nsys: %.12e\n", wct, ust, syt);

        // Memory clean up
        interval_destroy(&start_time);
        master_destroy(ntasks);
    } else {
        slave(test_stride);
    }

    // Shut down MPI.
    MPI_Finalize();
    return 0;
}

unit_work_t *get_next_work_item(void) {
    if( test_current_item + test_stride >= LIST_SIZE )
        return NULL;
    unit_work_t *tmp = &test_list[test_current_item+test_stride];
    test_current_item += test_stride;
    return tmp;
}

void process_results(unit_result_t result) {
    // Fill in with whatever is relevant to process the results returned by the
    // slave.
}
