// ****************************************************************************
//
//          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/>.
//
// ****************************************************************************

#ifndef AEVOL_PHYLOGENETIC_TREE_HANDLER_H_
#define AEVOL_PHYLOGENETIC_TREE_HANDLER_H_

#include <filesystem>

#include "AeTime.h"
#include "ae_types.h"
#include "Grid.h"
#include "Tree.h"

namespace aevol {

class PhylogeneticTreeHandler {
 public:
  PhylogeneticTreeHandler()                                          = delete;
  PhylogeneticTreeHandler(const PhylogeneticTreeHandler&)            = delete;
  PhylogeneticTreeHandler(PhylogeneticTreeHandler&&)                 = delete;
  PhylogeneticTreeHandler& operator=(const PhylogeneticTreeHandler&) = delete;
  PhylogeneticTreeHandler& operator=(PhylogeneticTreeHandler&&)      = delete;
  PhylogeneticTreeHandler(const std::filesystem::path& dir, int32_t nb_indivs, time_type output_frequency);
  virtual ~PhylogeneticTreeHandler()                                 = default;

  auto make_tree_path(time_type t) const -> std::filesystem::path;
  void report_new_indiv(const Individual* new_indiv,
                        const Individual* parent,
                        indiv_id_type indiv_id,
                        indiv_id_type parent_id);
  void report_mutation(time_type t, indiv_id_type indiv_id, std::unique_ptr<MutationReport> mutation);
  void report_end_of_replication(Individual* indiv, indiv_id_type indiv_id);
  void write_tree(time_type t);

 protected:
  std::filesystem::path dir_;
  std::unique_ptr<Tree> tree_;
};

}  // namespace aevol

#endif  // AEVOL_PHYLOGENETIC_TREE_HANDLER_H_
