///////////////////////////////////////////////////////////////////////////////////////
/// \file main.cpp
/// \brief Main module for command line version of LPJ-GUESS
///
/// \author Ben Smith
/// $Date: 2014-05-13 14:55:59 +0200 (Tue, 13 May 2014) $
///
///////////////////////////////////////////////////////////////////////////////////////

#include "config.h"
#include "guess.h"
#include "framework.h"
#include "commandlinearguments.h"
#include "parallel.h"
#include <stdlib.h>
#include "eceframework.h"

#ifdef __unix__
// includes needed for umask()
#include <sys/types.h>
#include <sys/stat.h>
#endif

///////////////////////////////////////////////////////////////////////////////////////
// LOG FILE
// The name of the log file to which output from all dprintf and fail calls is sent is
// set here

xtring file_log="guess.log";

// ecev3 - needed to initialise MPI with call to init(.,.) below.
using namespace GuessParallel;


///////////////////////////////////////////////////////////////////////////////////////
// MAIN
// This is the function called when the executable is run

int main(int argc,char* argv[]) {
	// Initialize parallel communication if available.
	// This needs to be done before command line parsing since some MPI
	// implementations put their own arguments in our command line
	// (which should then be removed after the MPI initialization).

	// ecev3 - moved this line from it's previous position below. 
	// Set our shell for the model to communicate with the world
	set_shell(new CommandLineShell(file_log));
	
	dprintf("Welcome to LPJ-GUESS! \n");

#ifdef __unix__

	// On unix systems we set the umask (which controls the file permissions
	// of files we create). Some MPI implementations set a restrictive umask
	// which would mean that other users can't read the files generated by
	// LPJ-GUESS.

	umask(S_IWGRP | S_IWOTH); // only disable write access for group and others

#endif

	// Parse command line arguments
	CommandLineArguments args(argc, argv);

	dprintf("Read CommandLineArguments ... \n");

	// ecev3 - initialise MPI if needed.
	init(argc, argv);

	// run_ecev3_not_cruncep
	// Change working directory according to rank if parallel, spinup run
	// this is now now done in runlpjguess()
	//if (args.get_parallel() && args.get_islpjgspinup() && !ECEARTHWITHCRUNCEP) {
	if (false) {
			int thisrank = GuessParallel::get_rank();
			xtring path;
			path.printf("./run%d", thisrank+1); // ecev3 - was rank+1

			dprintf("\nParallel LPJ-GUESS spinup, so creating directory on node %d\n",thisrank);

			if (change_directory(path) != 0) {
				fprintf(stderr, "Failed to change to run directory for a parallel LPJ-GUESS spinup\n");
				return EXIT_FAILURE;
			}
	}

	// run_cruncep_not_ecev3
	// Change working directory according to rank if parallel run
	if (args.get_parallel() && ECEARTHWITHCRUNCEP) {
		xtring path;
		path.printf("./run%d", GuessParallel::get_rank() + 1);

		if (change_directory(path) != 0) {
			fprintf(stderr, "Failed to change to run directory\n");
			return EXIT_FAILURE;
		}
	}

	// Set our shell for the model to communicate with the world
	// set_shell(new CommandLineShell(file_log)); // ecev3 - moved up!

	if (args.get_help()) {
		printhelp();
		return EXIT_SUCCESS;
	} 

	// Call the framework
	if (ECEARTHWITHCRUNCEP) {
		framework(args); // run_cruncep_not_ecev3
	}
	
	// ecev3 - call ecemain in eceframework.cpp instead
	if (!ECEARTHWITHCRUNCEP) {
		ecemain(args); // run_ecev3_not_cruncep
	}

	// Say goodbye
	dprintf("\nFinished\n");


	return EXIT_SUCCESS;
}
