/*
 * Copyright (C) 2016 QAware GmbH
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */
package de.qaware.chronix.solr.type.metric.functions.aggregations;

import de.qaware.chronix.server.functions.ChronixAggregation;
import de.qaware.chronix.server.functions.FunctionCtx;
import de.qaware.chronix.server.types.ChronixTimeSeries;
import de.qaware.chronix.timeseries.MetricTimeSeries;
import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;

import java.util.List;

/**
 * The range analysis returns the difference between the maximum and minimum of a time series
 *
 * @author f.lautenschlager
 */
public final class Range implements ChronixAggregation<MetricTimeSeries> {

    /**
     * Gets difference between the maximum and the minimum value.
     * It is always a positive value.
     *
     * @param timeSeries the time series
     * @return the average or 0 if the list is empty
     */
    @Override
    public void execute(List<ChronixTimeSeries<MetricTimeSeries>> timeSeriesList, FunctionCtx functionCtx) {
        //If it is empty, we return NaN
        if (timeSeries.size() <= 0) {
            functionCtx.add(this, Double.NaN);
            return;
        }

        //the values to iterate
        double[] values = timeSeries.getValuesAsArray();
        //Initialize the values with the first element
        double min = values[0];
        double max = values[0];

        for (int i = 1; i < values.length; i++) {
            double current = values[i];

            //check for min
            if (current < min) {
                min = current;
            }
            //check of max
            if (current > max) {
                max = current;
            }
        }
        //return the absolute difference
        functionCtx.add(this, Math.abs(max - min));
    }

    @Override
    public String getQueryName() {
        return "range";
    }

    @Override
    public String getType() {
        return "metric";
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (obj == this) {
            return true;
        }
        if (obj.getClass() != getClass()) {
            return false;
        }
        return new EqualsBuilder()
                .isEquals();
    }

    @Override
    public int hashCode() {
        return new HashCodeBuilder()
                .toHashCode();
    }
}

@@ -1404,16 +1404,20 @@
 meSeries
+List
  the tim
@@ -1609,24 +1609,196 @@
 nCtx) %7B%0A
+%0A        for (ChronixTimeSeries%3CMetricTimeSeries%3E chronixTimeSeries : timeSeriesList) %7B%0A%0A            MetricTimeSeries timeSeries = chronixTimeSeries.getRawTimeSeries();%0A%0A  
         
 //If it 
@@ -1789,16 +1789,18 @@
         
+  
 //If it 
@@ -1823,16 +1823,20 @@
 urn NaN%0A
+    
         
@@ -1869,32 +1869,36 @@
 ) %7B%0A            
+    
 functionCtx.add(
@@ -1913,16 +1913,48 @@
 uble.NaN
+, chronixTimeSeries.getJoinKey()
 );%0A     
@@ -1960,22 +1960,25 @@
         
+ 
-return
+   break
 ;%0A      
@@ -1975,27 +1975,35 @@
 ak;%0A        
+ 
-%7D%0A%0A
+   %7D%0A%0A    
         //th
@@ -2022,16 +2022,20 @@
 iterate%0A
+    
         
@@ -2091,16 +2091,20 @@
         
+    
 //Initia
@@ -2142,32 +2142,36 @@
 element%0A        
+    
 double min = val
@@ -2178,32 +2178,36 @@
 ues%5B0%5D;%0A        
+   
+ 
 double max = val
@@ -2211,24 +2211,28 @@
 values%5B0%5D;%0A%0A
+    
         for 
@@ -2277,24 +2277,28 @@
             
+    
 double curre
@@ -2318,32 +2318,36 @@
 %5D;%0A%0A            
+ 
+   
 //check for min%0A
@@ -2346,16 +2346,20 @@
 for min%0A
+    
         
@@ -2379,24 +2379,28 @@
 nt %3C min) %7B%0A
+    
             
@@ -2422,34 +2422,42 @@
 nt;%0A            
-%7D%0A
+    %7D%0A    
             //ch
@@ -2471,32 +2471,36 @@
 max%0A            
+   
+ 
 if (current %3E ma
@@ -2500,24 +2500,28 @@
 nt %3E max) %7B%0A
+    
             
@@ -2555,20 +2555,32 @@
     
-%7D%0A    
     %7D%0A
+            %7D%0A    
     
@@ -2616,16 +2616,20 @@
 ference%0A
+    
         
@@ -2669,18 +2669,60 @@
 x - min)
-);
+, chronixTimeSeries.getJoinKey());%0A        %7D
 %0A    %7D%0A%0A

Fix range logic.