#include <iostream>
#include <mpi.h>

#include "BarnesHutTree.hpp"
#include "MpiSimulation.hpp"
#include "Tree.hpp"

int main(int argc, char* argv[]) {
	MPI_Init(&argc, &argv);
	{
		int rank;
		MPI_Comm_rank(MPI_COMM_WORLD, &rank);

		if (argc < 2) {
			MPI_Finalize();
			std::cerr << "need input file parameter\n";
			return -1;
		}
		//initialize and load particles
		std::cout << "rank " << rank << ": initialize...\n";
		if (rank == 0) {
			std::cout << "rank 0: load particles ...\n";
		}
		nbody::MpiSimulation simulation{ std::string(argv[1]) };

		//initial particle and domain distribution
		if (rank == 0) {
			std::cout << "rank 0: distribute particles to other processes ...\n";
		}
		simulation.distributeBodies();
		std::cout << "rank " << rank << ": distributing initial domains to other processes ...\n";
		simulation.distributeDomains();
		simulation.buildTree();
		for (std::size_t i = 0; i < 3; i++) {
			//local tree is built and correct domains are distributed
			std::cout << "rank " << rank << ": running simulation step " << i << " ...\n";
			simulation.runStep();
		}
	}
	MPI_Finalize();
	return 0;
}
