package rdms;

import rdms.Meter;
import rdms.MeterRead;

import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class Extract {
	
	protected HashSet<Meter> meterList;
	protected HashSet<MeterRead> meterReadList;
	protected Map<Long,HashSet<MeterRead>> mappedList;
	protected Map<Long,MeterRead> summaryList;
	
	protected Map<Long,Float []> usageMaxMonthMap;
	protected float [] maxUsageSpecificMonth;
	
	public Extract() {
		meterList = new HashSet<Meter>();
		meterReadList = new HashSet<MeterRead>();
		mappedList = new HashMap<Long,HashSet<MeterRead>>();
		summaryList = new HashMap<Long,MeterRead>();
		
		usageMaxMonthMap = new HashMap<Long,Float[]>();
		maxUsageSpecificMonth = new float[12];
		for(int i = 0; i < 12; i++) {
			maxUsageSpecificMonth[i] = -1;
		}
	}
	
	public void connectToServer() {
		
	}
	public void closeServer() {
		
	}
	//
	public void printMeterInfo(Meter tempMeter) {
		System.out.println("      ____METER____");
		System.out.println("      ID: " + tempMeter.id);
		System.out.println("      Name: " + tempMeter.contact_name);
		System.out.println("      Email: " + tempMeter.email);
		System.out.println("      Number: " + tempMeter.phone_number);
		System.out.println("      Description: " + tempMeter.description);
		System.out.println("      Address: " + tempMeter.address);
		System.out.println("      City: " + tempMeter.city);
		System.out.println("      State OR Province: " + tempMeter.state_province);
		System.out.println("      Last Reading: " + tempMeter.last_reading);
		System.out.println("      Latitude: " + tempMeter.latitude);
		System.out.println("      Longitude: " + tempMeter.longitude);
	}
	public void printMeterReadInfo(MeterRead tempMeterRead) {
		System.out.println("            ---Meter_Read---");
		System.out.println("                  Timestamp:" + tempMeterRead.timestamp);
		System.out.println("                  Usage Since Read:" + tempMeterRead.usage_since_read);
		System.out.println("                  Usage This Day:" + tempMeterRead.usage_this_day);
		System.out.println("                  Usage This Week:" + tempMeterRead.usage_this_week);
		System.out.println("                  Usage This Month:" + tempMeterRead.usage_this_month);
		System.out.println("                  Usage This Year:" + tempMeterRead.usage_this_year);
		System.out.println("                  All Time Usage:" + tempMeterRead.all_time_usage);
		System.out.println("                  Error Code 1:" + tempMeterRead.error_code_1);
		System.out.println("                  Error Code 2:" + tempMeterRead.error_code_2);
	}
	public void gatherData() {
		
	}
	//
	public void clearDatabase() {
		
	}
	public void testFunction() {
		
	}

	//should try to improve performance on this, if possible
	public void createSummary() {
		Iterator<Meter> it = meterList.iterator();
		//
		while(it.hasNext()) {
			Meter met = new Meter();
			met = it.next();
			HashSet<MeterRead> mrSetTemp = mappedList.get(met.id);
			if(mappedList.containsKey(met.id) && !mappedList.get(met.id).isEmpty()) {
				Iterator<MeterRead> it1 = mrSetTemp.iterator();
				MeterRead maxUsagesMeterRead = new MeterRead();
				
				Calendar cal1 = Calendar.getInstance();
				int curMonth = 0;
				Float[] curMonthMax = new Float[12];
				for(int i = 0; i < 12; i++) {
					curMonthMax[i] = Float.valueOf(((float)(-1.0)));
				}
				while(it1.hasNext()) {
					MeterRead metr1 = new MeterRead();
					metr1 = it1.next();
					if(maxUsagesMeterRead.all_time_usage < metr1.all_time_usage) {
						maxUsagesMeterRead.all_time_usage = metr1.all_time_usage;
					}
					if(maxUsagesMeterRead.usage_this_month < metr1.usage_this_month) {
						maxUsagesMeterRead.usage_this_month = metr1.usage_this_month;
					}
					if(maxUsagesMeterRead.usage_this_week < metr1.usage_this_week) {
						maxUsagesMeterRead.usage_this_week = metr1.usage_this_week;
					}
					if(maxUsagesMeterRead.usage_this_year < metr1.usage_this_year) {
						maxUsagesMeterRead.usage_this_year = metr1.usage_this_year;
					}
					if(maxUsagesMeterRead.usage_this_day < metr1.usage_this_day) {
						maxUsagesMeterRead.usage_this_day = metr1.usage_this_day;
					}
					if(maxUsagesMeterRead.usage_since_read < metr1.usage_since_read) {
						maxUsagesMeterRead.usage_since_read = metr1.usage_since_read;
					}
					cal1.setTime(metr1.timestamp);
					curMonth = cal1.get(Calendar.MONTH) - 1;
					//if(curMonth == month) {
						if((float) metr1.usage_this_month > (float) curMonthMax[curMonth]) {
							curMonthMax[curMonth] = Float.valueOf(((float) metr1.usage_this_month));
						}
					//}
				}
				for(int i = 0; i < 12; i++) {
					if(curMonthMax[i] > maxUsageSpecificMonth[i]) {
						maxUsageSpecificMonth[i] = curMonthMax[i];
					}
				}
				usageMaxMonthMap.put(met.id, curMonthMax);
				// add the max usage to the report
				maxUsagesMeterRead.timestamp = met.last_reading;
				summaryList.put(met.id, maxUsagesMeterRead);
			}
		}
	}
	
	public void printSummary() {
		System.out.println("About to print data...");
		gatherData();
		createSummary();
		System.out.println("---Summary of Database---");
		System.out.println("    ___Summary of Months");
		for(int i = 1; i < 13; i++) {
			if(maxUsageSpecificMonth[(i-1)] > 0) {
				printSummaryMonth(i);
			}
		}
		//
		int yesN = 1;
		if(yesN == 1) {
			Set<Long> keySet1 = summaryList.keySet();
			Iterator<Long> it = keySet1.iterator();
			System.out.println("    ___Summary of IDs");
			while(it.hasNext()) {
				MeterRead m = new MeterRead();
				long curKey = it.next();
				m = summaryList.get(curKey);
				System.out.println("         " + "---Summary for ID " + curKey + "---");
				System.out.println("         " + "         " + "All Time Usage" + " Max: " + m.all_time_usage);
				System.out.println("         " + "         " + "Usage Since Read" + " Max: " + m.usage_since_read);
				System.out.println("         " + "         " + "Usage This Day" + " Max: " + m.usage_this_day);
				System.out.println("         " + "         " + "Usage This Week" + " Max: " + m.usage_this_week);
				System.out.println("         " + "         " + "Usage This Month" + " Max: " + m.usage_this_month);
				System.out.println("         " + "         " + "Usage This Year" + " Max: " + m.usage_this_year);
			}
		}
		//
		System.out.println("---End of Summary of the Database---");
	}
	public void printSummaryMonth(int month) {
		System.out.println("---Summary of Database Month " + month + "---");
		System.out.println("Max Usage of ALL database of Month " + month + ": " + maxUsageSpecificMonth[(month-1)]);
		System.out.println("Max Usage of Month " + month + " per ID: ");
		//Iterator it = super.usageMaxMonthMap.entrySet().iterator();
		Set<Long> keysID = usageMaxMonthMap.keySet();
		Iterator<Long> it2 = keysID.iterator();
		while(it2.hasNext()) {
			long key1 = it2.next();
			Float [] pairV = usageMaxMonthMap.get(key1);
			if(pairV[(month-1)] > 0) {
				System.out.println("         " + "Month Max of ID " + key1 + ": " + pairV[(month-1)]);
			}
		}
		/*
		while(it.hasNext()) {
			Map.Entry pair = (Map.Entry)it.next(); 
			Float [] pairV = (Float[]) pair.getValue();
			System.out.println("         " + "Month Max of ID " + pair.getKey() + ": " + pairV[(month-1)]);
			it.remove();
		}
		*/
		System.out.println("---End of Summary of Month " + month + "--");
	}
	public float calculateUsageMonth(long id, int monthnum) {
		return 0;
	}
	public void printData() {
		
	}
	public void printUsagesMonth(int monthnum) {
		Date d3 = new Date();
		for(int i = 1; i < 101; i++) {
			Date d1 = new Date();
			float totM = calculateUsageMonth(i,monthnum);
			Date d2 = new Date();
		}
		Date d4 = new Date();
	}
	public void run() {
		connectToServer();
		//
		int month = 8;
		Date d1 = new Date();
		float totM = calculateUsageMonth(1,month);
		Date d2 = new Date();
		System.out.println("Total for month " + month + ": " + totM);
		float elapsed = (float) ((1.0 * d2.getTime() - d1.getTime()) / 60.0);
		System.out.println("Elapsed time for Extract (month " + month + "): " + elapsed);
		//
		closeServer();
	}
	public void run2() {
		connectToServer();
		//printData();
		printSummary();
		closeServer();
	}
}