// ****************************************************************************
//
//          Aevol - An in silico experimental evolution platform
//
// ****************************************************************************
//
// Copyright: See the AUTHORS file provided with the package or <www.aevol.fr>
// Web: http://www.aevol.fr/
// E-mail: See <http://www.aevol.fr/contact/>
// Original Authors : Guillaume Beslon, Carole Knibbe, David Parsons
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.
//
// ****************************************************************************

#include "StatsOrchestrator.h"

#include "stats/SingleIndividualStatsHandler.h"
#include "stats/DefaultGlobalStatsData.h"
#include "stats/FitnessStatsData.h"
#include "stats/ChromosomeStatsData.h"
#include "stats/DiploidChromosomeStatsData.h"
#include "stats/MutationsStatsData.h"
#include "stats/DiploidMutationsStatsData.h"
#include "stats/DiploidNonCodingStatsData.h"

namespace aevol {

StatsOrchestrator::StatsOrchestrator(std::optional<time_type> best_indiv_stats_output_frequency,
                                     std::optional<time_type> whole_pop_stats_output_frequency)
    : best_indiv_stats_output_frequency_(best_indiv_stats_output_frequency),
      whole_pop_stats_output_frequency_(whole_pop_stats_output_frequency) {
}

void StatsOrchestrator::init_stats(time_type time) {
  const std::filesystem::path stats_dir = "stats";
  std::filesystem::create_directories(stats_dir);

  if (best_indiv_stats_output_frequency_) {
    auto stats_best_filename = stats_dir / "stats_best.csv";
    if (time == 0) {
      if (exp_setup->diploid()) {
        best_indiv_stats_handlers_.push_back(
            SingleIndividualStatsHandler<DefaultGlobalStatsData,
                                         FitnessStatsData,
                                         DiploidChromosomeStatsData,
                                         DiploidMutationsStatsData,
                                         DiploidNonCodingStatsData>::make_empty(stats_best_filename));
      } else {
        best_indiv_stats_handlers_.push_back(
            SingleIndividualStatsHandler<DefaultGlobalStatsData,
                                         FitnessStatsData,
                                         ChromosomeStatsData,
                                         MutationsStatsData>::make_empty(stats_best_filename));
      }
    } else {
      if (exp_setup->diploid()) {
        best_indiv_stats_handlers_.push_back(
            SingleIndividualStatsHandler<DefaultGlobalStatsData,
                                         FitnessStatsData,
                                         DiploidChromosomeStatsData,
                                         DiploidMutationsStatsData,
                                         DiploidNonCodingStatsData>::make_resume(stats_best_filename, time));
      } else {
        best_indiv_stats_handlers_.push_back(
            SingleIndividualStatsHandler<DefaultGlobalStatsData,
                                         FitnessStatsData,
                                         ChromosomeStatsData,
                                         MutationsStatsData>::make_resume(stats_best_filename, time));
      }
    }
  }

  if (whole_pop_stats_output_frequency_) {
    auto stats_mean_filename = stats_dir / "stats_mean.csv";
    if (time == 0) {
      mean_stats_handler_ = std::decay_t<decltype(*mean_stats_handler_)>::make_empty(stats_mean_filename);
    } else {
      mean_stats_handler_ = std::decay_t<decltype(*mean_stats_handler_)>::make_resume(stats_mean_filename, time);
    }
  }
}

}  // namespace aevol
