// ****************************************************************************
//
//          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 "PhylogeneticTreeHandler.h"

#include <format>
#include <fstream>

namespace aevol {

PhylogeneticTreeHandler::PhylogeneticTreeHandler(
    const std::filesystem::path& dir, int32_t nb_indivs, time_type output_frequency)
    : dir_(dir) {
  tree_ = std::make_unique<Tree>(nb_indivs, output_frequency);
}

auto PhylogeneticTreeHandler::make_tree_path(time_type t) const -> std::filesystem::path {
  return dir_ / std::format("tree_{:0>9}.ae", t);
}

void PhylogeneticTreeHandler::report_new_indiv(const Individual* new_indiv,
                                               const Individual* parent,
                                               indiv_id_type indiv_id,
                                               indiv_id_type parent_id) {
  tree_->update_new_indiv(new_indiv, parent, indiv_id, parent_id);
}

void PhylogeneticTreeHandler::report_mutation(
    time_type t, indiv_id_type indiv_id, std::unique_ptr<MutationReport> mutation) {
  tree_->report_by_index(t, indiv_id)->dna_replic_report().add_mut(std::move(mutation));
}

void PhylogeneticTreeHandler::report_end_of_replication(Individual* indiv, indiv_id_type indiv_id) {
  tree_->update_end_replication(indiv, indiv_id);
}

void PhylogeneticTreeHandler::write_tree(time_type t) {
  std::filesystem::create_directories(dir_);
  tree_->write_to_tree_file(make_tree_path(t).c_str());
}

}  // namespace aevol
