#ifndef PARAMETEROPTIMIZER_H
#define PARAMETEROPTIMIZER_H

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

#include "SearchHeuristic.h"
#include "analysis.h"

struct ConfidenceInterval {
    ConfidenceInterval(double d, double m, double u, double t=-1) : down{d}, mean{m}, up{u}, thresold{t} {};

    double down;
    double mean;
    double up;
    double thresold;
};

struct TestWave {
    TestWave(int nb, double q, int d=0) : nb_tests{nb}, slq{q}, depth{d} {};
    int nb_tests;
    double slq; // Student Law Quartile
    int depth;
};

class ParameterOptimizer
{
    public:
        ParameterOptimizer(std::default_random_engine& randomizer);
        virtual ~ParameterOptimizer();
        // Algorithms
        virtual SearchHeuristic* get_context(unsigned int num_context, double parameter, std::default_random_engine& randomizer) = 0;
        virtual std::string display_context(unsigned int num_context);
        void set_nb_contexts(unsigned int nb_contexts);
        // Interval
        void set_study_interval(double initial_parameter, double final_parameter, double parameter_step);
        // Test waves
        void add_test_wave(int nb_tests, double student_law_quartile, int depth=0);
        // Running
        virtual std::string get_context_for_csvfile(unsigned int num_context);
        void save_run(std::string filename);
        std::vector<ConfidenceInterval> run_step(int num_step=0, bool displaying=true);
        std::vector<ConfidenceInterval> run_step(int num_step, int first_context, int nb_explored_contexts, double initial_parameter, double final_parameter, double parameter_step, bool displaying=true);
        std::vector<ConfidenceInterval> run(bool displaying=true);

    protected:

    private:
        unsigned int m_nb_contexts;
        std::default_random_engine& m_randomizer;
        double m_initial_parameter;
        double m_final_parameter;
        double m_parameter_step;
        std::vector<TestWave> m_waves;
        bool m_saving_in_csvfile;
        std::string m_csvfile_name;
};

#endif // PARAMETEROPTIMIZER_H
