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

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import cz.muni.fi.lasaris.sbms.data.entities.Address;
import cz.muni.fi.lasaris.sbms.data.entities.AddressGroup;
import cz.muni.fi.lasaris.sbms.data.entities.AggregationFunction;
import cz.muni.fi.lasaris.sbms.data.entities.SeriesSpecs;
import cz.muni.fi.lasaris.sbms.data.entities.containers.Aggregation;
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.containers.TrendGroup;
import cz.muni.fi.lasaris.sbms.data.entities.values.AggregatedValue;
import cz.muni.fi.lasaris.sbms.data.entities.values.InterpolatedValue;

public interface TrendsProvider {
		
		public void init(Properties props, String name, String propertiesPrefix);
		
		public void close();
	
		// returns time series - either with interpolation or raw data
		public Trend getTrend(Address trend, SeriesSpecs s);
		
		// complete trend data for multiple trends - used for custom aggregation or direct inspection 
		public TrendGroup getTrends(List<Address> trends, SeriesSpecs s);
		
		// trend data provided in groups - used for custom aggregations
		public Map<String, TrendGroup> getTrendsByGroup(List<AddressGroup> trends, SeriesSpecs s);
		
		// returns aggregated value for given trend
		public AggregatedValue getTrendAggregation(Address trend, SeriesSpecs seriesSpecs, AggregationFunction aggregation);
		
		// returns aggregated values for each of the trends
		public Aggregation<Address> getTrendAggregations(List<Address> trend, SeriesSpecs seriesSpecs, AggregationFunction aggregation);
		
		// aggregations over time and groups
		public Aggregation<AddressGroup> getGroupTrendAggregations(List<AddressGroup> trend, SeriesSpecs seriesSpecs, AggregationFunction aggregation);
		
		// methods that might perform some sort of interpolation - return one value for one moment in time
		public InterpolatedValue getTrendValue(Address trend, LocalDateTime timestamp);
		
		// returns slice - for each address one value at give time (interpolation will likely occur)
		public Slice getSlice(List<Address> trends, LocalDateTime timestamp);
		
		// returns "slices" - values of trends in given time (equivalent to repeated call to getTrendValues with different timestamps)
		public Series<Slice> getSlices(List<Address> trends, SeriesSpecs seriesSpecs);
		
		// creates aggregation over "slices" - performs aggregation on the slice, not on the individual trend
		public Series<AggregatedValue> getSliceAggregations(List<Address> trends, SeriesSpecs seriesSpecs, AggregationFunction aggregation);
		
		// aggregations over slice and group
		public Series<Aggregation<AddressGroup>> getGroupSliceAggregations(List<AddressGroup> trends, SeriesSpecs seriesSpecs, AggregationFunction aggregation);
		
}
