package rdms;

import rdms.Ingest;
import rdms.Meter;
import rdms.MeterRead;
//import rdms.ServerConnection;

import java.io.FileInputStream;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.Properties;
import java.util.Random;

import com.toshiba.mwcloud.gs.Collection;
import com.toshiba.mwcloud.gs.GSException;
import com.toshiba.mwcloud.gs.GridStore;
import com.toshiba.mwcloud.gs.GridStoreFactory;
import com.toshiba.mwcloud.gs.Query;
import com.toshiba.mwcloud.gs.RowSet;
import com.toshiba.mwcloud.gs.TimeSeries;

public class GridDBIngest extends Ingest {
	private String indexName2 = "METERS";
	private String indexName1 = "METER_READS";
	
	private Collection<String,Meter> metersCol;
	private HashMap<String,MeterRead> dataMap;
	
	private Query<Meter> meterQuery;
	private RowSet<Meter> meterRows;
	//
	Properties sourceProps = new Properties();
	GridStore store;
	//
	
	@Override
	public void setUp2(Collection<String,Meter> mcol, RowSet<Meter> mrows, Query<Meter> mquery) {
		this.metersCol = mcol;
		this.meterRows = mrows;
		this.meterQuery = mquery;
	}
	
	private void setUp() {
		try {
			this.metersCol = store.putCollection(indexName2, Meter.class);
			this.dataMap = new HashMap<String,MeterRead>();
			this.meterQuery = metersCol.query("select * ");
			this.meterRows = meterQuery.fetch(false);
			this.metersCol.setAutoCommit(false);
		} catch (GSException e) {
			e.printStackTrace();
		}
	}
	
	private boolean meterExists(long key) {
		String s = Long.toString(key);
		try {
			this.metersCol.get(s);
			return true;
		} catch (GSException e) {
			return false;
		}
	}
	@Override
	public boolean checkMeterExistsDB(long key) {
		//return meterExists(key);
		return true;
	}
	private boolean meterReadExists(Date key, long key1) {
		TimeSeries<MeterRead> tempMeterRead;
		try {
			tempMeterRead = store.getTimeSeries(indexName1 + "_" + key1,MeterRead.class);
			tempMeterRead.get(key);
			return true;
		} catch (GSException e) {
			return false;
		}
		
	}
	@Override
	public Meter getMeterFromDB(long key) {
		/*
		String s = key + "";
		try {
			return metersCol2.get(s);
		} catch (GSException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return new Meter();
		}
		*/
		return getLastMeterFromDB();
	}
	public Meter getLastMeterFromDB() {
		RowSet<Meter> rowSetTemp = meterRows;
		int num = 0;
		try {
			while(rowSetTemp.hasNext() && num == 0) {
				try {
					return rowSetTemp.next();
				} catch (Exception e) {
					return super.meter;
				}
			}
		} catch (GSException e) {
			return super.meter;
		}
		return super.meter;
	}
	private MeterRead getMeterReadGridDB(Date key, long key1) {
		TimeSeries<MeterRead> tempMeterRead;
		try {
			tempMeterRead = store.getTimeSeries(indexName1 + "_" + key1,MeterRead.class);
			return tempMeterRead.get(key);
		} catch (GSException e) {
			e.printStackTrace();
			return new MeterRead();
		}
	}
	public MeterRead getMeterReadFromDB(Date key) {
		TimeSeries<MeterRead> tempMeterRead;
		try {
			tempMeterRead = store.getTimeSeries(indexName1 + "_" + super.meter.id,MeterRead.class);
			return tempMeterRead.get(key);
		} catch (GSException e) {
			e.printStackTrace();
			return new MeterRead();
		}
	}
	
	@Override
	public void connectToServer() {
		InputStream input;
		boolean debug = true;
		boolean worked = false;
		try {
			input = new FileInputStream("rdms/source.properties");
			sourceProps.load(input);
		} catch (Exception e) {
			System.out.println("COULD NOT LOAD source.properties");
		}
		if(debug) {
			System.out.println("SOURCE PROPS:");
			System.out.println(sourceProps);
		}
		try {
			store = GridStoreFactory.getInstance().getGridStore(sourceProps);
			worked = true;
		} catch (GSException e) {
			System.out.println("Could not connect to GridDB");
			e.printStackTrace();
		}
		if(debug && worked)
			System.out.println("Connected to GridDB!");
		
		setUp();
	}
	
	@Override
	public void connectToServer(GridStore s) {
		this.store = s;
		super.isSet = true;
	}
	@Override
	public void closeServer() {
		try {
			store.close();
		} catch (GSException e) {
			System.out.println("Could not close server");
			e.printStackTrace();
		}
	}
	
	@Override
	public void writeToDatabase() {
		try {
			TimeSeries<MeterRead> meterData = store.putTimeSeries(indexName1 + "_" + super.meter.id, MeterRead.class);
			meterData.setAutoCommit(false);
			metersCol.put(super.meter);
			metersCol.commit();
			meterData.put(super.meterRead.timestamp, super.meterRead);
			meterData.commit();
			System.out.println("Done writing to DB");
		} catch (GSException e) {
			System.out.println("Could not write to Database");
			e.printStackTrace();
		}
		
	}
}