#include <BarnesHutTree.hpp>
#include <MpiSimulation.hpp>
#include <iostream>
#include <mpi.h>
#include <cstdlib>
#include <Tree.hpp>

using namespace nbody;
using namespace std;

int main(int argc, char* argv[]) {
	MPI_Init(&argc, &argv);
	if (argc < 2) {
		MPI_Finalize();
		cerr << "need input file parameter" << endl;
		return -1;
	}
	MpiSimulation simulation;
	int rank;

	MPI_Comm_rank(MPI_COMM_WORLD, &rank);
	//initialize and load particles
	cout << "  " << "rank " << rank << ": initialize..." << endl;
	if (rank == 0) {
		cout << "  " << "rank 0: load particles ..." << endl;
	}
	simulation.initialize(string(argv[1]));
	//initial particle and domain distribution
	if (rank == 0) {
		cout << "  " << "rank 0: distribute particles to other processes ..." << endl;
	}
	simulation.distributeBodies();
	cout << "  " << "rank " << rank << ": distributing initial domains to other processes ..." << endl;
	simulation.distributeDomains();
	cout << "  " << "rank " << rank << ": building initial trees ..." << endl;
	simulation.buildTree();
	for (int i = 0; i < 3; i++) {
		//local tree is built and correct domains are distributed
		cout << "running simulation step " << i << " ..." << endl;
		simulation.runStep();
	}
	simulation.cleanup();
	MPI_Finalize();
	return 0;
}
