package org.opencb.commons.datastore.solr;

import org.apache.solr.client.solrj.response.QueryResponse;
import org.apache.solr.common.util.SimpleOrderedMap;
import org.opencb.commons.datastore.core.result.FacetQueryResultItem;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

public class SolrFacetToFacetQueryResultItemConverter {

    public FacetQueryResultItem convert(QueryResponse solrResponse) {
        // Sanity check
        if (solrResponse == null || solrResponse.getResponse() == null || solrResponse.getResponse().get("facets") == null) {
            return null;
        }

        SimpleOrderedMap<Object> solrFacets = (SimpleOrderedMap<Object>) solrResponse.getResponse().get("facets");
        List<FacetQueryResultItem.FacetField> facetFields = new ArrayList<>();
        int count = (int) solrFacets.get("count");
        for (int i = 0; i < solrFacets.size(); i++) {
            String name = solrFacets.getName(i);
            if (!"count".equals(name)) {
                if (solrFacets.get(name) instanceof SimpleOrderedMap) {
                    FacetQueryResultItem.FacetField facetField = new FacetQueryResultItem.FacetField(name, count, new ArrayList<>());
                    parseBuckets((SimpleOrderedMap<Object>) solrFacets.get(name), facetField);
                    facetFields.add(facetField);
                } else {
                    facetFields.add(parseAggregation(name, solrFacets.get(name)));
                }
            }
        }

        return new FacetQueryResultItem(facetFields);
    }

    private void parseBuckets(SimpleOrderedMap<Object> solrFacets, FacetQueryResultItem.FacetField facetField) {
        List<SimpleOrderedMap<Object>> solrBuckets = (List<SimpleOrderedMap<Object>>) solrFacets.get("buckets");
        List<FacetQueryResultItem.Bucket> buckets = new ArrayList<>();
        for (SimpleOrderedMap<Object> solrBucket: solrBuckets) {
            int count = 0;
            String value = "";
            FacetQueryResultItem.FacetField subfield;
            List<FacetQueryResultItem.FacetField> subfields = new ArrayList<>();
            for (int i = 0; i < solrBucket.size(); i++) {
                String fullname = solrBucket.getName(i);
                if ("count".equals(fullname)) {
                    count = (int) solrBucket.getVal(i);
                } else if ("val".equals(fullname)) {
                    value = solrBucket.getVal(i).toString();
                } else {
                    if (solrBucket.getVal(i) instanceof SimpleOrderedMap) {
                        String[] split = fullname.split("__");
                        subfield = new FacetQueryResultItem.FacetField(split[0], count, new ArrayList<>());
                        if (split.length > 3) {
                            subfield.setStart(Integer.parseInt(split[1]));
                            subfield.setEnd(Integer.parseInt(split[2]));
                            subfield.setStep(Integer.parseInt(split[3]));
                        }

                        parseBuckets((SimpleOrderedMap<Object>) solrBucket.getVal(i), subfield);
                    } else {
                        subfield = parseAggregation(fullname, solrBucket.getVal(i));
                    }
                    subfields.add(subfield);
                }
            }
            FacetQueryResultItem.Bucket bucket = new FacetQueryResultItem.Bucket(value, count, subfields);
            bucket.setFacetFields(subfields);
            buckets.add(bucket);
        }
        facetField.setBuckets(buckets);
    }

    private FacetQueryResultItem.FacetField parseAggregation(String fullname, Object value) {
        String[] split = fullname.split("__");
        String fieldName = split[0];
        String aggregationName = split[1];
        if (split.length > 3) {
            aggregationName += ("(" + split[2]);
            for (int i = 3; i < split.length - 1; i++) {
                aggregationName += ("," + split[i]);
            }
            aggregationName += ")";
        }
        List<Double> values;
        if (value instanceof Double[]) {
            values = Arrays.asList((Double[]) value);
        } else {
            values = Collections.singletonList((Double) value);
        }
        return new FacetQueryResultItem.FacetField(fieldName, aggregationName, values);
    }
}

@@ -242,122 +242,613 @@
 til.
-ArrayList;%0Aimport java.util.Arrays;%0Aimport java.util.Collections;%0Aimport java.util.List;%0A%0Apublic class SolrFacetTo
+*;%0A%0Apublic class SolrFacetToFacetQueryResultItemConverter %7B%0A%0A    public static FacetQueryResultItem convert(QueryResponse solrResponse) %7B%0A        return convert(solrResponse, new HashMap%3C%3E());%0A    %7D%0A%0A    /**%0A     * Convert a generic solrResponse into our FacetQueryResultItem.%0A     *%0A     * @param solrResponse SolrResponse.%0A     * @param solrKeyMap Map containing the solr keys present in the solrResponse and the key we actually want to be visible for the user.%0A     *                   This is mainly to be able to hide private solr keys to the user and use better user-friendly keys.%0A     * @return a 
 Face
@@ -859,36 +859,33 @@
 ryResultItem
-Converter %7B%0A
+.%0A     */
 %0A    public 
@@ -884,16 +884,23 @@
  public 
+static 
 FacetQue
@@ -938,32 +938,64 @@
 nse solrResponse
+, Map%3CString, String%3E solrKeyMap
 ) %7B%0A        // S
@@ -1730,21 +1730,80 @@
 etField(
-name,
+solrKeyMap.getOrDefault(name, name),%0A                           
  count, 
@@ -1906,32 +1906,44 @@
 ame), facetField
+, solrKeyMap
 );%0A             
@@ -2082,16 +2082,28 @@
 et(name)
+, solrKeyMap
 ));%0A    
@@ -2214,16 +2214,23 @@
 private 
+static 
 void par
@@ -2318,16 +2318,85 @@
 cetField
+,%0A                                     Map%3CString, String%3E solrKeyMap
 ) %7B%0A    
@@ -3406,23 +3406,90 @@
 ld(s
-plit%5B0%5D, count,
+olrKeyMap.getOrDefault(split%5B0%5D, split%5B0%5D), count,%0A                               
  new
@@ -3888,32 +3888,44 @@
 Val(i), subfield
+, solrKeyMap
 );%0A             
@@ -4022,16 +4022,28 @@
 etVal(i)
+, solrKeyMap
 );%0A     
@@ -4391,16 +4391,23 @@
 private 
+static 
 FacetQue
@@ -4476,16 +4476,48 @@
 ct value
+, Map%3CString, String%3E solrKeyMap
 ) %7B%0A    
@@ -5156,25 +5156,61 @@
 etField(
-fieldName
+solrKeyMap.getOrDefault(fieldName, fieldName)
 , aggreg

make methods of the SolrFacetResult converter static.