package cz.muni.fi.lasaris.sbms.data.util;

import java.time.ZonedDateTime;
import java.util.Iterator;
import java.util.Map;

import cz.muni.fi.lasaris.sbms.data.entities.Address;
import cz.muni.fi.lasaris.sbms.data.entities.containers.Series;
import cz.muni.fi.lasaris.sbms.data.entities.containers.Slice;
import cz.muni.fi.lasaris.sbms.data.entities.containers.Trend;
import cz.muni.fi.lasaris.sbms.data.entities.values.InterpolatedValue;

public class Slicer {
	/**
	 * Creates Slices from sampled/windowed trends. The trends must be previously sampled by the 
	 * Sampler.computeSampling or WindowMaker.computeWindows method! If not,
	 * the method will behave unpredictable - failing with NUllPointerException and mixing up data.
	 * This method only changes the structure of the data.
	 * @param data 
	 * @param s
	 * @return
	 */
	public static Series<Slice> createSlices(Map<Address, Trend> data) {
		if(data == null) {
			throw new IllegalArgumentException("no data to process");
		}
		Series<Slice> r = new Series<Slice>();
		if((data.size() == 0)) {
			return r;
		}
		Iterator<Address> i = data.keySet().iterator();
		Address a = i.next();
		// first trend - creates the slices during the creation
		Trend t = data.get(a);
		for(ZonedDateTime dt : t.getKeys()) {
			Slice s = new Slice();
			s.add(a, ((InterpolatedValue)t.get(dt)));
			r.add(dt, s);
		}
		
		// looping through trends
		while(i.hasNext()) {
			a = i.next();
			t = data.get(a);
			// using iterator might be little faster than calling get for each ZonedDateTime from original trend
			Iterator<Slice> i2 = r.getData().values().iterator();
			// we rely on sampling and do not perform any other checks
			// looping through records
			for(ZonedDateTime dt : t.getKeys()) {
				Slice s = i2.next();
				s.add(a, (InterpolatedValue)t.get(dt));
			}
		}
		
		return r;
	}
}
