#! /usr/bin/python3
import math
import numpy as np
import csv
import readStateTable
import subprocess
CSV = 'state_table.csv'
HADOOP = "/usr/local/hadoop/bin/hadoop" #path to hadoop
JARNAME = "analysis.jar"
CLASSNAME = "com.cs435.quince.Main"
INPUTDIRECTORY = "/hourly_88101/hourly_88101.csv" #in hdfs
OUTPUTDIRECTORY = "/predictions" #in hdfs
LOCALOUTPUT = "." # unless changed local output will be put wherever this script runs


#Script to use mapreduce on EPA data to predict pm2.5 emissions

#maximum number of years we will predict
MAXYEARS = np.inf

#globals that will hold current request parameters
STARTLAT = np.inf;
ENDLAT = np.inf;
STATE = None
STARTLON = np.inf;
ENDLON = np.inf;
USERYEARS = np.inf;

print("driver started")


#-------------------GET PARAMETERS FROM USER INPUT----------------

def getState():
	state = input('Enter Desired State name or abbreviation:')
	if(validateState(state)):
		return readStateTable.getCorrespondingState(state,CSV)
	else:
		return None

def validateState(state):
	state = readStateTable.getCorrespondingState(state,CSV)
	valid = state is not None
	if(valid):
		return True
	else:
		return False

def getLatitude(type = ""):
	lat = float(input('Enter Desired '+ type+ ' Latitude:'))
	if(validateLatitude(lat)):
		return lat
	else:
		return np.inf

def validateLatitude(lat):
	return not np.isnan(lat) and abs(lat) >= 0 and abs(lat) <= 90;


def getLongitude(type = ""):
	lon = float(input('Enter Desired '+ type+ ' Longitude:'))
	if(validateLongitude(lon)):
		return lon
	else:
		return np.inf

def validateLongitude(lon):
	return not np.isnan(lon) and abs(lon) >= 0 and abs(lon) <= 180;

def getYears():
	years = float(input('Enter Desired Years:'))
	if(validateYears(years,MAXYEARS)):
		return years
	else:
		return np.inf

def validateYears(years,maxYears = np.inf):
	overMax = False;
	if(not np.isinf(maxYears)):
		overMax = years > maxYears
	return not np.isnan(years) and years >= 0 and not overMax;



#--------------------SET PARAMETERS TO MAKE MAPREDUCE CALL-----------
def setStartLatitude(start):
	global STARTLAT
	STARTLAT = start

def setEndLatitude(end):
	global ENDLAT
	ENDLAT = end

def setStartLongitude(start):
	global STARTLON
	STARTLON = start

def setEndLongitude(end):
	global ENDLON
	ENDLON = end

def setYears(years):
	global USERYEARS
	USERYEARS = years

def setState(state):
	global STATE
	STATE = state


#-------------------Request User Input to set Parameters-----------

def printCurrentParameters():
	if(parametersNotInfLatLon()):
		myString = 'Start:%d,%d - End:%d,%d  Years:%d ' % (STARTLAT,STARTLON,ENDLAT,ENDLON,USERYEARS)
	elif(parametersValid()):
		myString = 'State:%s, Years:%d' % (STATE,USERYEARS)
	else:
		myString = "Parameters not valid"
	print(myString)

def parametersNotInfLatLon():
	if(np.isinf(STARTLAT) or np.isinf(ENDLAT) or np.isinf(STARTLON) or np.isinf(ENDLON) or np.isinf(USERYEARS)):
		return False
	else:
		return True

def parametersValid():
	if(STATE is None or np.isinf(USERYEARS)):
		return False
	else:
		return True

def requestParametersLatLon():
	setStartLatitude(getLatitude('Start'))
	setEndLatitude(getLatitude('End'))
	setStartLongitude(getLongitude('Start'))
	setEndLongitude(getLongitude('End'))
	setYears(getYears())
	if(parametersNotInf()):
		printCurrentParameters()
	else:
		print("Invalid Parameters entered, Valid Ranges: lat: +- 0-90 lon:+- 0-180 years: 0-"+str(MAXYEARS))
		requestParameters()

def requestParameters():
	setState(getState())
	setYears(getYears())
	if(parametersValid()):
		printCurrentParameters()
	else:
		print("Invalid Parameters entered,  enter full state name or abbreviation \n years: 0-"+str(MAXYEARS))
		requestParameters()
#-----------------------------Call to HADOOP---------------------------------------------
def callHadoop():
	#hadoop analysis.jar com.cs435.quince.Main <numyears> <state> <inputdir> <outputdir>
	subprocess.call([HADOOP,"jar",JARNAME,CLASSNAME,str(USERYEARS),STATE,INPUTDIRECTORY,OUTPUTDIRECTORY])
	subprocess.call([HADOOP,"fs","-get", OUTPUTDIRECTORY, LOCALOUTPUT])
#-----------------------------Plot Results-----------------------------------------------
def plotResults(resultsDirectory):
	print("plot results is not implemented")
#------------------------------MAIN------------------------------------------------------
def main():
	requestParameters()
	callHadoop()

main()
