#ifndef ANALYSIS_H_INCLUDED
#define ANALYSIS_H_INCLUDED

#include <iostream>
#include <chrono>
#include <vector>

#include "SearchHeuristic.h"

std::chrono::time_point<std::chrono::system_clock> start_chrono() {
    return std::chrono::system_clock::now();
}
std::chrono::time_point<std::chrono::system_clock> stop_chrono() {
    return std::chrono::system_clock::now();
}
int interval_chrono(std::chrono::time_point<std::chrono::system_clock> start, std::chrono::time_point<std::chrono::system_clock> stop) {
    return std::chrono::duration_cast<std::chrono::milliseconds>(stop-start).count();
}

struct Statistic {
    Statistic(double avg, double mini, double maxi, double med, double dev) :
        average{avg}, minimal{mini}, maximal{maxi}, median{med}, deviation{dev} {};

    double average;
    double minimal;
    double maximal;
    double median;
    double deviation;
};

Statistic avg_calls(SearchHeuristic& algo, MasterMind problem, int nb=100) {
    std::vector<double> data;
    Statistic stat(0,0,0,0,0);
    for(int i=0; i<nb; i++) {
        algo.set_problem(&problem);
        Result res = algo.run();
        delete[] res.solution;
        data.push_back(res.nb_calls);
        stat.average += res.nb_calls;
        if(i == 0) {
            stat.minimal = res.nb_calls;
            stat.maximal = res.nb_calls;
        }
        if(res.nb_calls > stat.maximal)
            stat.maximal = res.nb_calls;
        if(res.nb_calls < stat.minimal)
            stat.minimal = res.nb_calls;
    }
    stat.average /= nb;

    for(int i=0; i<nb; i++)
        stat.deviation += pow(data[i] - stat.average, 2);
    stat.deviation = sqrt(stat.deviation/nb);
    return stat;
}

#endif // ANALYSIS_H_INCLUDED
