// Path: chronix-server-plugin-management/src/main/java/de/qaware/chronix/server/functions/ChronixAggregation.java
// public interface ChronixAggregation<T> extends ChronixFunction<T> {
// 
// 
//     @Override
//     default FunctionType getFunctionType() {
//         return FunctionType.AGGREGATION;
//     }
// 
//     default String[] getArguments() {
//         return new String[0];
//     }
// 
//     @Override
//     default void setArguments(String[] args) {
//         //do nothing
//     }
// }
// 
// Path: chronix-server-plugin-management/src/main/java/de/qaware/chronix/server/functions/FunctionCtx.java
// public class FunctionCtx {
// 
//     //TODO: Check if we need this.
//     private final Map<String, FunctionCtxEntry> functionCtxEntries = Collections.synchronizedMap(new HashMap<>());
// 
//     private final int maxAmountOfAggregations;
//     private final int maxAmountOfAnalyses;
//     private final int maxAmountOfTransformations;
// 
// 
//     /**
//      * A container for analyses and its results
//      *
//      * @param amountOfAggregations    the number of aggregations
//      * @param amountOfAnalyses        the number of analyses
//      * @param amountOfTransformations the number of transformations
//      */
//     public FunctionCtx(int amountOfAggregations, int amountOfAnalyses, int amountOfTransformations) {
//         this.maxAmountOfAggregations = amountOfAggregations;
//         this.maxAmountOfAnalyses = amountOfAnalyses;
//         this.maxAmountOfTransformations = amountOfTransformations;
//     }
// 
//     /**
//      * Appends the analysis to the result
//      *
//      * @param analysis the chronix analysis
//      * @param value    the value for the analysis
//      */
//     public void add(ChronixAnalysis analysis, boolean value, String joinKey) {
//         addEntryIfNotExist(joinKey);
//         functionCtxEntries.get(joinKey).add(analysis, value);
//     }
// 
//     /**
//      * Append the aggregation to the result
//      *
//      * @param aggregation the chronix aggregation
//      * @param value       the value of the aggregation
//      */
//     public void add(ChronixAggregation aggregation, double value, String joinKey) {
//         addEntryIfNotExist(joinKey);
//         functionCtxEntries.get(joinKey).add(aggregation, value);
//     }
// 
//     /**
//      * Appends the transformation to the result
//      *
//      * @param transformation add an transformation
//      */
//     public void add(ChronixTransformation transformation, String joinKey) {
//         addEntryIfNotExist(joinKey);
//         functionCtxEntries.get(joinKey).add(transformation);
//     }
// 
//     private synchronized void addEntryIfNotExist(String joinKey) {
//         if (!functionCtxEntries.containsKey(joinKey)) {
//             functionCtxEntries.put(joinKey, new FunctionCtxEntry(maxAmountOfTransformations, maxAmountOfAggregations, maxAmountOfAnalyses));
//         }
//     }
// 
//     /**
//      * @param joinKey used to create groups time series chunks
//      * @return the entry in the function context for this time series
//      */
//     public FunctionCtxEntry getContextFor(String joinKey) {
//         return functionCtxEntries.get(joinKey);
//     }
// }
// 
// Path: chronix-server-plugin-management/src/main/java/de/qaware/chronix/server/types/ChronixTimeSeries.java
// public interface ChronixTimeSeries<T> {
// 
//     /**
//      * @return the type of the chronix time series
//      */
//     String getType();
// 
//     /**
//      * @return the name of the time series
//      */
//     String getName();
// 
//     /**
//      * @return the start of the time series
//      */
//     long getStart();
// 
//     /**
//      * @return the end of the time series
//      */
//     long getEnd();
// 
//     /**
//      * @return the getAttributes
//      */
//     Map<String, Object> getAttributes();
// 
//     /**
//      * Sorts the time series by time acceding
//      */
//     void sort();
// 
//     /**
//      * @return the data as json
//      */
//     String dataAsJson();
// 
//     /**
//      * @return as binary large object
//      */
//     byte[] dataAsBlob();
// 
//     /**
//      * @return the join key
//      */
//     String getJoinKey();
// 
//     /**
//      * @return get raw time series
//      */
//     T getRawTimeSeries();
// }


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 org.apache.commons.lang3.builder.ToStringBuilder;
import java.util.List;
/*
 * Copyright (C) 2018 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;



/**
 * Percentile aggregation analysis
 *
 * @author f.lautenschlager
 */
public final class Percentile implements ChronixAggregation<MetricTimeSeries> {

    private double percentile;

    /**
     * Calculates the percentile of the first time series.
     *
     * @param timeSeriesList list with time series
     * @return the percentile or 0 if the list is empty
     */
    @Override
    public void execute(List<ChronixTimeSeries<MetricTimeSeries>> timeSeriesList, FunctionCtx functionCtx) {
// Path: chronix-server-plugin-management/src/main/java/de/qaware/chronix/server/functions/ChronixAggregation.java
// public interface ChronixAggregation<T> extends ChronixFunction<T> {
// 
// 
//     @Override
//     default FunctionType getFunctionType() {
//         return FunctionType.AGGREGATION;
//     }
// 
//     default String[] getArguments() {
//         return new String[0];
//     }
// 
//     @Override
//     default void setArguments(String[] args) {
//         //do nothing
//     }
// }
// 
// Path: chronix-server-plugin-management/src/main/java/de/qaware/chronix/server/functions/FunctionCtx.java
// public class FunctionCtx {
// 
//     //TODO: Check if we need this.
//     private final Map<String, FunctionCtxEntry> functionCtxEntries = Collections.synchronizedMap(new HashMap<>());
// 
//     private final int maxAmountOfAggregations;
//     private final int maxAmountOfAnalyses;
//     private final int maxAmountOfTransformations;
// 
// 
//     /**
//      * A container for analyses and its results
//      *
//      * @param amountOfAggregations    the number of aggregations
//      * @param amountOfAnalyses        the number of analyses
//      * @param amountOfTransformations the number of transformations
//      */
//     public FunctionCtx(int amountOfAggregations, int amountOfAnalyses, int amountOfTransformations) {
//         this.maxAmountOfAggregations = amountOfAggregations;
//         this.maxAmountOfAnalyses = amountOfAnalyses;
//         this.maxAmountOfTransformations = amountOfTransformations;
//     }
// 
//     /**
//      * Appends the analysis to the result
//      *
//      * @param analysis the chronix analysis
//      * @param value    the value for the analysis
//      */
//     public void add(ChronixAnalysis analysis, boolean value, String joinKey) {
//         addEntryIfNotExist(joinKey);
//         functionCtxEntries.get(joinKey).add(analysis, value);
//     }
// 
//     /**
//      * Append the aggregation to the result
//      *
//      * @param aggregation the chronix aggregation
//      * @param value       the value of the aggregation
//      */
//     public void add(ChronixAggregation aggregation, double value, String joinKey) {
//         addEntryIfNotExist(joinKey);
//         functionCtxEntries.get(joinKey).add(aggregation, value);
//     }
// 
//     /**
//      * Appends the transformation to the result
//      *
//      * @param transformation add an transformation
//      */
//     public void add(ChronixTransformation transformation, String joinKey) {
//         addEntryIfNotExist(joinKey);
//         functionCtxEntries.get(joinKey).add(transformation);
//     }
// 
//     private synchronized void addEntryIfNotExist(String joinKey) {
//         if (!functionCtxEntries.containsKey(joinKey)) {
//             functionCtxEntries.put(joinKey, new FunctionCtxEntry(maxAmountOfTransformations, maxAmountOfAggregations, maxAmountOfAnalyses));
//         }
//     }
// 
//     /**
//      * @param joinKey used to create groups time series chunks
//      * @return the entry in the function context for this time series
//      */
//     public FunctionCtxEntry getContextFor(String joinKey) {
//         return functionCtxEntries.get(joinKey);
//     }
// }
// 
// Path: chronix-server-plugin-management/src/main/java/de/qaware/chronix/server/types/ChronixTimeSeries.java
// public interface ChronixTimeSeries<T> {
// 
//     /**
//      * @return the type of the chronix time series
//      */
//     String getType();
// 
//     /**
//      * @return the name of the time series
//      */
//     String getName();
// 
//     /**
//      * @return the start of the time series
//      */
//     long getStart();
// 
//     /**
//      * @return the end of the time series
//      */
//     long getEnd();
// 
//     /**
//      * @return the getAttributes
//      */
//     Map<String, Object> getAttributes();
// 
//     /**
//      * Sorts the time series by time acceding
//      */
//     void sort();
// 
//     /**
//      * @return the data as json
//      */
//     String dataAsJson();
// 
//     /**
//      * @return as binary large object
//      */
//     byte[] dataAsBlob();
// 
//     /**
//      * @return the join key
//      */
//     String getJoinKey();
// 
//     /**
//      * @return get raw time series
//      */
//     T getRawTimeSeries();
// }


// Path: chronix-server-type-metric/src/main/java/de/qaware/chronix/solr/type/metric/functions/aggregations/Percentile.java
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 org.apache.commons.lang3.builder.ToStringBuilder;
import java.util.List;

/*
 * Copyright (C) 2018 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;



/**
 * Percentile aggregation analysis
 *
 * @author f.lautenschlager
 */
public final class Percentile implements ChronixAggregation<MetricTimeSeries> {

    private double percentile;

    /**
     * Calculates the percentile of the first time series.
     *
     * @param timeSeriesList list with time series
     * @return the percentile or 0 if the list is empty
     */
    @Override
    public void execute(List<ChronixTimeSeries<MetricTimeSeries>> timeSeriesList, FunctionCtx functionCtx) {
        for (ChronixTimeSeries<MetricTimeSeries> chronixTimeSeries : timeSeriesList) {