#ifndef ANALYSIS_H_INCLUDED
#define ANALYSIS_H_INCLUDED

#include <iostream>
#include <chrono>
#include <vector>
#include <algorithm>
#include <fstream>

#include "heuristics/SearchHeuristic.h"

// Statistic
struct Statistic {
    Statistic() : Statistic(0,0,0,0,0,0,0) {};
    Statistic(double n, double s, double avg, double mini, double maxi, double med, double dev) :
        nb{n}, sum{s}, average{avg}, minimal{mini}, maximal{maxi}, median{med}, deviation{dev} {
            no_bias_deviation = 0;
            alea = 0;
            label = 0;
    };

    double nb;
    double sum;
    double average;
    double minimal;
    double maximal;
    double median;
    double deviation;
    double no_bias_deviation;
    double alea;
    double label;
};

// Chrono Functions
std::chrono::time_point<std::chrono::system_clock> start_chrono();
std::chrono::time_point<std::chrono::system_clock> stop_chrono();
int interval_chrono(std::chrono::time_point<std::chrono::system_clock> start, std::chrono::time_point<std::chrono::system_clock> stop);

// Averaged Executions
Statistic avg_calls(SearchHeuristic* algo, int nb=100, double abortion_limit=-1, double student_law_quartile=-1);
Statistic* avg_evolution(SearchHeuristic* algo, int max_evolution, int nb_tests = 100);
void cmp_evolution(std::vector<SearchHeuristic*> algos, MasterMind& problem, std::string outfilename, int max_evolution, int nb_tests = 100);

// Complexity Tools
std::vector<Statistic> compute_complexity(std::default_random_engine& randomizer, SearchHeuristic* algo, int n_initial, int n_final, int n_step=1, int nb_tests=100, double slq=-1, bool displaying=true);
void save_in_file(std::string namefile, std::vector<Statistic> stats);

#endif // ANALYSIS_H_INCLUDED
