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

import static org.junit.Assert.*;

import java.util.LinkedHashMap;
import java.util.Map;

import org.junit.Before;
import org.junit.Test;

import cz.muni.fi.lasaris.sbms.data.entities.Address;
import cz.muni.fi.lasaris.sbms.data.entities.AggregationFunction;
import cz.muni.fi.lasaris.sbms.data.entities.ValueState;
import cz.muni.fi.lasaris.sbms.data.entities.values.AggregatedValue;
import cz.muni.fi.lasaris.sbms.data.entities.values.RawValue;
import cz.muni.fi.lasaris.sbms.data.util.Aggregator;

public class AggregationsTest {

	Map<Address, RawValue> data;
	Map<Address, RawValue> empty = new LinkedHashMap<Address, RawValue>();
	
	@Before
	public void setUp() throws Exception {
		data = new LinkedHashMap<Address, RawValue>();
		data.put(new Address("bacnet://4600.AV.91", new double[] {0.8, 4}), new RawValue(66.8));
		data.put(new Address("bacnet://4600.AV.91", new double[] {0.4, 6}), new RawValue(6.8));
		data.put(new Address("bacnet://4600.BV.91"), new RawValue(true));
		data.put(new Address("bacnet://4600.AV.71", new double[] {0.3, 4}), new RawValue(4));
		data.put(new Address("bacnet://4600.MV.81"), new RawValue("ahoj"));
		data.put(new Address("bacnet://4600.BV.91"), new RawValue(false));
	}

	@Test
	public void testComputeAggregation() {
		AggregatedValue v = null;
		
		v = Aggregator.computeAggregation(data, AggregationFunction.COUNT);
		assertEquals(6, ((Long)v.getValue()).intValue());
		assertEquals(AggregationFunction.COUNT, v.getAggregation());
		
		v = Aggregator.computeAggregation(data, AggregationFunction.MAX);
		assertEquals(66.8, ((Double)v.getValue()).doubleValue(), 0.1);
		assertEquals(AggregationFunction.MAX, v.getAggregation());
		
		v = Aggregator.computeAggregation(data, AggregationFunction.MIN);
		assertEquals(4, ((Double)v.getValue()).doubleValue(), 0.1);
		assertEquals(AggregationFunction.MIN, v.getAggregation());
		
		v = Aggregator.computeAggregation(data, AggregationFunction.MEDIAN);
		assertEquals(6.8, ((Double)v.getValue()).doubleValue(), 0.1);
		assertEquals(AggregationFunction.MEDIAN, v.getAggregation());
		
		v = Aggregator.computeAggregation(data, AggregationFunction.SUM);
		assertEquals(77.6, ((Double)v.getValue()).doubleValue(), 0.1);
		assertEquals(AggregationFunction.SUM, v.getAggregation());
		
		v = Aggregator.computeAggregation(data, AggregationFunction.AVG);
		assertEquals(25.86, ((Double)v.getValue()).doubleValue(), 0.1);
		assertEquals(AggregationFunction.AVG, v.getAggregation());
		
		v = Aggregator.computeAggregation(data, AggregationFunction.WEIGHTED_AVG);
		assertEquals(34.54, ((Double)v.getValue()).doubleValue(), 0.1);
		assertEquals(AggregationFunction.WEIGHTED_AVG, v.getAggregation());
		
		v = Aggregator.computeAggregation(data, AggregationFunction.AND);
		assertEquals(false, ((Boolean)v.getValue()).booleanValue());
		assertEquals(AggregationFunction.AND, v.getAggregation());
		
		v = Aggregator.computeAggregation(data, AggregationFunction.OR);
		assertEquals(true, ((Boolean)v.getValue()).booleanValue());
		assertEquals(AggregationFunction.OR, v.getAggregation());
		
		v = Aggregator.computeAggregation(data, AggregationFunction.RATIO);
		assertEquals(0.5, ((Double)v.getValue()).doubleValue(), 0.01);
		assertEquals(AggregationFunction.RATIO, v.getAggregation());
		
		// ------------------------------------------------
		
		v = Aggregator.computeAggregation(empty, AggregationFunction.MAX);
		assertEquals(ValueState.FAIL, v.getState());
		
		v = Aggregator.computeAggregation(empty, AggregationFunction.MIN);
		assertEquals(ValueState.FAIL, v.getState());
		
		v = Aggregator.computeAggregation(empty, AggregationFunction.MEDIAN);
		assertEquals(ValueState.FAIL, v.getState());
		
		v = Aggregator.computeAggregation(empty, AggregationFunction.SUM);
		assertEquals(ValueState.FAIL, v.getState());
		
		v = Aggregator.computeAggregation(empty, AggregationFunction.AND);
		assertEquals(ValueState.FAIL, v.getState());
		
		v = Aggregator.computeAggregation(empty, AggregationFunction.OR);
		assertEquals(ValueState.FAIL, v.getState());
		
		v = Aggregator.computeAggregation(empty, AggregationFunction.RATIO);
		assertEquals(ValueState.FAIL, v.getState());
		
	}
	
	@Test
	public void testDouble() {
		Double a = Double.valueOf(4);
		assertEquals(Double.compare(a, Double.valueOf(5)), -1);
	}

}
