from datetime import datetime

def getRawDataTotalLoad(startDate, endDate, location, customArgs= {}):
	return reports.MBR.totalpower.getRawDataTotalLoad(startDate, endDate, location, customArgs)

def getRawDataCriticalLoad(startDate, endDate, location, customArgs= {}):
	return reports.MBR.totalpower.getRawDataCriticalLoad(startDate, endDate, location, customArgs= {})


def stripHistColumns(histDS, colsToKeep=[]):
	"""
		Support function to remove standalone columns
	"""
	histHeaders = system.dataset.getColumnHeaders(histDS)
	newHeader = [histHeaders[0]] + colsToKeep
	
	allRows = []
	for row in histDS:
		allRows.append([row[c] for c in newHeader])
	
	return system.dataset.toPyDataSet(system.dataset.toDataSet((newHeader, allRows)))

def processCalcPeakAvg(histDS, keyCol, colNames, interval):
	"""
	Calculate peak and avg by interval
	Args:
		histDS: history dataset to process
		keyCol: identify the key column to calculate from
		colNames: new column names for peak and avg
		interval: histDS should be in minute intervals, how many rows per grouping
	Returns:
		dataset of t_stamp, Peak<keyCol>, Avg<keyCol>
		GroupDict of interval raw values
	"""
	timeUnitStr = ""
	GroupDict= {} # represents {"datetime":{"col1":[], "col2":[]...}}
	histDsCols = [keyCol]
	resultData = []
	for i,row in enumerate(histDS):
		if i%interval == 0: 
			timeUnitStr = system.date.format(row["t_stamp"],"yyyy-MM-dd HH:mm")
			GroupDict.setdefault(timeUnitStr, {})
			GroupDict[timeUnitStr]={"values":[]}
#		GroupDict[quarterHrStr].append(row["SumRealPwr"])
		for col in histDsCols:
			GroupDict[timeUnitStr]["values"].append(row[col] if row[col] is not None else 0)
	sortedDateKeys = sorted(GroupDict.keys(), key=lambda x: datetime.strptime(x, '%Y-%m-%d %H:%M'))
	for dt_str in sortedDateKeys:		
		intervalAvg = sum(GroupDict[dt_str]["values"])/len(GroupDict[dt_str]["values"])
		intervalPeak = max(GroupDict[dt_str]["values"])
		oneRow = [system.date.parse(dt_str, "yyyy-MM-dd HH:mm"), intervalPeak, intervalAvg]
		resultData.append(oneRow)
	
	return system.dataset.toPyDataSet(system.dataset.toDataSet(["t_stamp"]+colNames, resultData)), GroupDict

def calcPUE(totalLoadDict, critLoadDict):
	resultData = []
	sortedDateKeys = sorted(totalLoadDict.keys(), key=lambda x: datetime.strptime(x, '%Y-%m-%d %H:%M'))
	
	for dt_str in sortedDateKeys:
		pue_intervalList= [a/b if b> 0 else -1 for a,b in zip(critLoadDict[dt_str]["values"], totalLoadDict[dt_str]["values"])]
		resultData.append([system.date.parse(dt_str, "yyyy-MM-dd HH:mm"), max(pue_intervalList), sum(pue_intervalList)/len(pue_intervalList)])		

	return system.dataset.toPyDataSet(system.dataset.toDataSet(["t_stamp","PeakPUE", "AvgPUE"], resultData))

def beginReport(startDate, endDate, intervalMin=15, location=None):
	"""
		Single call point for Report data fetch
	"""
	totalLoadHist = getRawDataTotalLoad(startDate, endDate, location)
	critLoadHist = getRawDataCriticalLoad(startDate, endDate, location)
	
#	rawData = reports.MBR.common.util.mergeHistorianData(totalLoadHist, critLoadHist)
	
	totalLoadHist = reports.MBR.common.util.generateSumCol(totalLoadHist, sumColName="TotalLoad")
	totalLoadHist, totalLoadDict = processCalcPeakAvg(totalLoadHist, "TotalLoad", ["PeakTotalLoad","AvgTotalLoad"], intervalMin)
	critLoadHist = reports.MBR.common.util.generateSumCol(critLoadHist, sumColName="CriticalLoad")
	critLoadHist, critLoadDict = processCalcPeakAvg(critLoadHist, "CriticalLoad", ["PeakCriticalLoad","AvgCriticalLoad"], intervalMin)
	
	pueData = calcPUE(totalLoadDict, critLoadDict)
	
	summaryData = reports.MBR.common.util.mergeHistorianData(totalLoadHist, critLoadHist)
	summaryData = reports.MBR.common.util.mergeHistorianData(summaryData, pueData)
	
	return {"summaryData": summaryData}
	