/*
* HydroPlus is source code and models developed and managed by Theodore Endreny and his students at SUNY ESF, te@esf.edu
* The US Forest Service and Davey Tree have provided strategic software development support through funding and personnel
* Attribution for use of software and code is requested.
* Cool River:
*	Abdi, R., Endreny, T., & Nowak, D. (2020). A model to integrate urban river thermal cooling in river restoration. Journal of Environmental Management, 258, 110023. doi:https://doi.org/10.1016/j.jenvman.2019.110023
*	Abdi, R., & Endreny, T. (2019). A River Temperature Model to Assist Managers in Identifying Thermal Pollution Causes and Solutions. Water, 11(5). doi:10.3390/w11051060
* Cool Air: 
*	Yang, Y., Endreny, T. A., & Nowak, D. J. (2013). A physically based analytical spatial air temperature and humidity model. Journal of Geophysical Research-Atmospheres, 118(18), 10449-10463. doi:10.1002/jgrd.50803
* Hydro: 
*	Yang, Y., & Endreny, T. A. (2013). Watershed hydrograph model based on surface flow diffusion. Water Resources Research, 49(1), 507-516. doi:10.1029/2012wr012186
*	Yang, Y., Endreny, T. A., & Nowak, D. J. (2011). i-Tree Hydro: Snow Hydrology Update for the Urban Forest Hydrology Model. Journal of the American Water Resources Association (JAWRA), 47(6), 1211-1218. doi:10.1111/j.1752-1688.2011.00564.x
*	Wang, J., Endreny, T. A., & Nowak, D. J. (2008). Mechanistic Simulation of Tree Effects in an Urban Water Balance Model. Journal of the American Water Resources Association, 44(1), 75-85. doi:10.1111/j.1752-1688.2007.00139.x
* Buffer:
*	Stephan, E. A., & Endreny, T. A. (2016). Weighting Nitrogen and Phosphorus Pixel Pollutant Loads to Represent Runoff and Buffering Likelihoods. JAWRA Journal of the American Water Resources Association, 52(2), 336-349. doi:doi:10.1111/1752-1688.12390
*	Endreny, T., & Wood, E. F. (2003). Watershed Weighting of Export Coefficients to Map Critical Phosphorus Loading Areas. Journal of the American Water Resources Association, 39(1), 165-181. 
*/
/*
*Development:
* 1. Statistical distribution of tree species, height, dbh; options for these runs:
*	a. run model time series with 1 tree type, then repeat for all tree types, get run average output weighted by tree type fraction; this allows variation in soil, etc.
*	b. run model with for loop within time step to include each tree type, get time step average tree weighted by tree type fraction
*/

#include <iostream>
#include "Inputs/Inputs.h"
#include "DataOrganizer.h"
#include "SimulationCoordinator.h"
#include "BuildDataOrganizer.h"
#include <chrono>
#include "Inputs/WeatherProcessor.h"

using namespace std;

typedef chrono::high_resolution_clock Clock;

//main is principal function for HydroPlus
int main(int argc, char* argv[])
{
	//Defining time_clock_start as record of current time with clock function
	auto time_clock_start = Clock::now();
		
	// TODO: update example to HydroPlus/TestingFilesAndScript/TestCases/HydroStatistical/GI_Bioretention/input																										
	//If Directory_Input_CLArg string length property is zero, then error handle with message.
	if (argc < 2 || argv[1] == NULL) {
		cout << "Notice: The HydroPlus command line input (CLI) argument was missing a file path to the input folder." << endl;
		cout << "Example Windows CLI: HydroPlus.exe C:/iTree/HydroPlus/TestingFilesAndScript/TestCases/GreenInfrastructure/Bioretention/input." << endl;
		cout << "Example Linux CLI: ./HydroPlusLinux /iTree/HydroPlus/TestingFilesAndScript/TestCases/HydroStatistical/GI_Bioretention/input" << endl;																																		
		cout << "Encouragement: If needed, then build your confidence with the example so you can design more sustainable communities." << endl;
		//Call abort function, which ends the HydroPlus.exe simulation
		abort();
	}
	//Command Line Input (CLI) argument argv[1] is assigned to string called Directory_Input_CLArg, path to HydroPlusConfig.xml
	string Directory_Input_CLArg = argv[1];

#if defined(__linux__) || defined(__gnu_linux__)
	cout << "Linux environment detected." << endl;
#endif
#if defined(_WIN32) || defined(_WIN64) || defined(_WIN16)
	cout << "Windows environment detected." << endl;
#endif
	//Directory_Input_CLArg is updated by EnsureTrailingBackslash function to ensure it has no parenthesis and ends with backslash
	Directory_Input_CLArg = EnsureTrailingBackslash(Directory_Input_CLArg);

	//Calling Inputs and sending CLI argument Directory_Input_CLArg path to HydroPlusConfig.xml
	Inputs *input = new Inputs(Directory_Input_CLArg);
	cout << "Completed Inputs functions." << endl;

	//Defining organizer as pointer for a new DataOrganizer structure, which will be passed in functions below
	DataOrganizer *organizer = new DataOrganizer;

	//If Model_Selection is not SpatialBuffer or ECDynamic then enter the DataOrganizer functions
	if (input->SimulationStringParams["Model_Selection"] != "SpatialBuffer" && input->SimulationStringParams["Model_Selection"] != "ECDynamic"){
		//Calling BulidDataOrganizer::BuildDataOrganizer_Manager function to call Model specific build functions
		//Note: sending pointers to organizer and input and Directory_Input_CLArg
		BuildDataOrganizer::BuildDataOrganizer_Manager(organizer, input, &input->beC, Directory_Input_CLArg);
		cout << "Completed DataOrganizer functions. All input data were organized into folders for simulation." << endl;
	}
	//Defining WeatherPro as pointer for a new WeatherProcessor structure
	WeatherProcessor* WeatherPro = new WeatherProcessor();

	//Calling SimulationCoordinator and sending pointers to organizer, input, and Directory_Input_CLArg
	SimulationCoordinator::SimulationCoordinator_Launch(organizer, input, &input->beC, WeatherPro, Directory_Input_CLArg);

	//Call delete functions for input, organizer, and WeatherPre
	delete input;
	delete organizer;
	delete WeatherPro;

	//Defining time_clock_end as record of current time with clock function
	auto time_clock_end = Clock::now();
	//Defining run time variable dur = t2 - t1
	int duration_simulation_s = int(chrono::duration_cast<chrono::seconds>(time_clock_end - time_clock_start).count());
	cout << "Simulation completed within " << duration_simulation_s << " seconds. Check output folder for results." << endl;
	cout << "Thank you for using i-Tree tools to improve the world!" << endl << endl;
}
