package org.eclipse.smila.solr.search;

import java.util.ArrayList;
import java.util.List;

import junit.framework.TestCase;

import org.apache.solr.client.solrj.impl.CloudSolrServer;
import org.apache.solr.client.solrj.response.QueryResponse;
import org.apache.solr.client.solrj.response.SolrResponseBase;
import org.apache.solr.common.SolrDocument;
import org.apache.solr.common.SolrDocumentList;
import org.apache.solr.common.params.CursorMarkParams;
import org.apache.solr.common.util.NamedList;
import org.apache.solr.common.util.SimpleOrderedMap;
import org.eclipse.smila.datamodel.AnyMap;
import org.eclipse.smila.datamodel.AnySeq;
import org.eclipse.smila.datamodel.DataFactory;
import org.eclipse.smila.datamodel.Record;
import org.eclipse.smila.search.api.SearchResultConstants;
import org.eclipse.smila.solr.SolrConfig;
import org.eclipse.smila.solr.SolrConstants;
import org.eclipse.smila.solr.params.SolrParams;

public class SolrResponseParser_Test extends TestCase {

  private final String ID_FIELD = "_recordid";

  private final DataFactory _factory = DataFactory.DEFAULT;

  private SolrConfig getSolrConfig() {
    final AnyMap config = _factory.createAnyMap();
    final AnyMap idFields = config.getMap(SolrConfig.ID_FIELDS, true);
    idFields.put(ID_FIELD, ID_FIELD);
    final SolrConfig solrConfig = new SolrConfig(config);
    return solrConfig;
  }

  public void test_toRecordResponseBaseDefault() {
    final SolrResponseBase solrResponse = new SolrResponseBase();
    {
      final NamedList<Object> response = new NamedList<>();
      final NamedList<Object> responseHeader = new NamedList<>();
      responseHeader.add("key", "val");
      responseHeader.add("key2", "val2");
      response.add(SolrConstants.RESPONSE_HEADER, responseHeader);
      solrResponse.setResponse(response);
    }
    final ResponseParser parser = new ResponseParser(_factory.createRecord(), getSolrConfig(), ID_FIELD);
    final Record result = parser.toRecord(solrResponse);
    final AnyMap responseHeader =
      result.getMetadata().getMap(SolrParams.SOLR_PARAMETER_ATTRIBUTE).getMap(ResponseAccessor.RESPONSE)
        .getMap(SolrConstants.RESPONSE_HEADER);
    assertNotNull(responseHeader);
    assertEquals("val", responseHeader.getStringValue("key"));
    assertEquals("val2", responseHeader.getStringValue("key2"));
  }

  public void test_parseFieldFacets() {
    final NamedList<Object> response = new NamedList<>();
    {
      final NamedList<Object> facetCounts = new NamedList<>();
      response.add("facet_counts", facetCounts);

      final NamedList<NamedList<Number>> facetFields = new NamedList<>();
      facetCounts.add("facet_fields", facetFields);
      final NamedList<Number> facetField = new NamedList<>();
      facetFields.add("field", facetField);
      facetField.add("from", 1);
      facetField.add("to", 2);

    }
    final QueryResponse queryResponse = new QueryResponse(response, new CloudSolrServer("localhost"));
    final ResponseParser parser = new ResponseParser(_factory.createRecord(), getSolrConfig(), ID_FIELD);
    {
      final Record result = parser.toRecord(queryResponse);
      final AnyMap facets = result.getMetadata().getMap(SearchResultConstants.FACETS);
      assertNotNull(facets);
      final AnyMap from = facets.getSeq("field").getMap(0);
      final AnyMap to = facets.getSeq("field").getMap(1);
      assertNotNull(from);
      assertNotNull(to);
      assertEquals("from", from.getStringValue(SearchResultConstants.VALUE));
      assertEquals(1, from.getLongValue(SearchResultConstants.COUNT).intValue());
      assertEquals("to", to.getStringValue(SearchResultConstants.VALUE));
      assertEquals(2, to.getLongValue(SearchResultConstants.COUNT).intValue());
    }
  }

  public void test_parseRangeFacets() {
    final NamedList<Object> response = new NamedList<>();
    {
      final NamedList<Object> facetCounts = new NamedList<>();
      response.add("facet_counts", facetCounts);

      final NamedList<NamedList<Object>> facetRanges = new NamedList<>();
      facetCounts.add("facet_ranges", facetRanges);
      final NamedList<Object> facetRange = new NamedList<>();
      facetRanges.add(SolrConstants.RANGE, facetRange);
      facetRange.add(SolrConstants.GAP, 5);
      facetRange.add(SolrConstants.START, 1);
      facetRange.add(SolrConstants.END, 10);
      facetRange.add("before", 2);
      facetRange.add("after", 3);
      facetRange.add("between", 4);
      final NamedList<Integer> counts = new NamedList<>();
      counts.add("one", 1);
      counts.add("two", 2);
      facetRange.add("counts", counts);
    }
    final QueryResponse queryResponse = new QueryResponse(response, new CloudSolrServer("localhost"));
    final ResponseParser parser = new ResponseParser(_factory.createRecord(), getSolrConfig(), ID_FIELD);
    {
      final Record result = parser.toRecord(queryResponse);
      final AnySeq range = result.getMetadata().getMap(SolrConstants.FACETS).getSeq(SolrConstants.RANGE);
      assertNotNull(range);
      final AnyMap one = range.getMap(0);
      final AnyMap two = range.getMap(1);
      assertEquals("one", one.getStringValue(SearchResultConstants.VALUE));
      assertEquals(1, one.getLongValue(SearchResultConstants.COUNT).intValue());
      assertEquals("two", two.getStringValue(SearchResultConstants.VALUE));
      assertEquals(2, two.getLongValue(SearchResultConstants.COUNT).intValue());
    }
  }

  public void test_parseQueryFacets() {
    final NamedList<Object> response = new NamedList<>();
    {
      final NamedList<Object> facetCounts = new NamedList<>();
      response.add("facet_counts", facetCounts);

      final NamedList<Integer> facetQueries = new NamedList<>();
      facetCounts.add("facet_queries", facetQueries);
      facetQueries.add("query1", 1);
      facetQueries.add("query2", 2);
    }
    final QueryResponse queryResponse = new QueryResponse(response, new CloudSolrServer("localhost"));
    final ResponseParser parser = new ResponseParser(_factory.createRecord(), getSolrConfig(), ID_FIELD);
    {
      final Record result = parser.toRecord(queryResponse);
      final AnySeq queries = result.getMetadata().getMap(SolrConstants.FACETS).getSeq(SolrConstants.QUERIES);
      assertNotNull(queries);
      final AnyMap one = queries.getMap(0);
      final AnyMap two = queries.getMap(1);
      assertNotNull(one);
      assertNotNull(two);
      assertEquals("query1", one.getStringValue(SearchResultConstants.VALUE));
      assertEquals(1, one.getLongValue(SearchResultConstants.COUNT).intValue());
      assertEquals("query2", two.getStringValue(SearchResultConstants.VALUE));
      assertEquals(2, two.getLongValue(SearchResultConstants.COUNT).intValue());
    }
  }

  public void test_parseIntervalFacets() {
    final NamedList<Object> response = new NamedList<>();
    {
      final NamedList<Object> facetCounts = new NamedList<>();
      response.add("facet_counts", facetCounts);

      final NamedList<NamedList<Object>> facetIntervals = new NamedList<>();
      facetCounts.add("facet_intervals", facetIntervals);
      final NamedList<Object> facetInterval = new NamedList<>();
      facetIntervals.add("title", facetInterval);
      facetInterval.add("0-5", 2);
      facetInterval.add("6-10", 3);
    }
    final QueryResponse queryResponse = new QueryResponse(response, new CloudSolrServer("localhost"));
    final ResponseParser parser = new ResponseParser(_factory.createRecord(), getSolrConfig(), ID_FIELD);
    {
      final Record result = parser.toRecord(queryResponse);
      final AnySeq title = result.getMetadata().getMap(SearchResultConstants.FACETS).getSeq("title");
      assertNotNull(title);
      assertEquals("0-5", title.getMap(0).getStringValue(SearchResultConstants.VALUE));
      assertEquals(2, title.getMap(0).getLongValue(SearchResultConstants.COUNT).intValue());
      assertEquals("6-10", title.getMap(1).getStringValue(SearchResultConstants.VALUE));
      assertEquals(3, title.getMap(1).getLongValue(SearchResultConstants.COUNT).intValue());
    }
  }

  public void test_grouping() {
    final NamedList<Object> response = new NamedList<>();
    {
      final NamedList<Object> grouped = new NamedList<>();
      response.add("grouped", grouped);

      final String fieldName = "author";
      final SimpleOrderedMap<Object> fieldGroups = new SimpleOrderedMap<>();
      grouped.add(fieldName, fieldGroups);

      final Integer matches = 3;
      final Integer nGroups = 2;
      final ArrayList<SimpleOrderedMap<Object>> groups = new ArrayList<>();
      final SimpleOrderedMap<Object> groupsMap = new SimpleOrderedMap<>();
      groups.add(groupsMap);
      groupsMap.add("groupValue", "Mann");
      groupsMap.add("doclist", new SolrDocumentList());
      final SolrDocumentList docList = new SolrDocumentList();

      fieldGroups.add(SearchResultConstants.MATCHES, matches);
      fieldGroups.add(SolrConstants.NGROUPS, nGroups);
      fieldGroups.add(SearchResultConstants.GROUPS, groups);
      fieldGroups.add("doclist", docList);
    }

    final QueryResponse queryResponse = new QueryResponse(response, new CloudSolrServer("localhost"));

    final ResponseParser parser = new ResponseParser(_factory.createRecord(), getSolrConfig(), ID_FIELD);
    {
      final Record result = parser.toRecord(queryResponse);
      final Long matches =
        result.getMetadata().getMap(SearchResultConstants.GROUPS).getLongValue(SearchResultConstants.MATCHES);
      assertEquals(3, matches.intValue());
      final AnyMap author = result.getMetadata().getMap(SearchResultConstants.GROUPS).getSeq("author").getMap(0);
      assertEquals("Mann", author.getStringValue(SearchResultConstants.VALUE));
      assertEquals(0, author.getLongValue(SearchResultConstants.COUNT).intValue());
      assertEquals(0, author.getSeq(SearchResultConstants.RESULTS).size());
    }

  }

  public void test_parseTerms() {
    final NamedList<Object> response = new NamedList<>();
    {
      final NamedList<NamedList<Number>> terms = new NamedList<>();
      response.add(SolrConstants.TERMS, terms);

      final NamedList<Number> fieldName1 = new NamedList<>();
      final NamedList<Number> fieldName2 = new NamedList<>();
      terms.add("fieldName1", fieldName1);
      terms.add("fieldName2", fieldName2);

      fieldName1.add("name1", 23);
      fieldName1.add("name2", 32);

      fieldName2.add("name3", 5);
      fieldName2.add("name4", 12);
    }
    final QueryResponse queryResponse = new QueryResponse(response, new CloudSolrServer("localhost"));
    final ResponseParser parser = new ResponseParser(_factory.createRecord(), getSolrConfig(), ID_FIELD);
    {
      final Record result = parser.toRecord(queryResponse);
      final AnyMap terms =
        result.getMetadata().getMap(SolrParams.SOLR_PARAMETER_ATTRIBUTE).getMap(ResponseAccessor.RESPONSE)
          .getMap(SolrConstants.TERMS);
      assertNotNull(terms.get("fieldName1"));
      assertNotNull(terms.get("fieldName2"));
      assertEquals(23, terms.getMap("fieldName1").getLongValue("name1").intValue());
      assertEquals(32, terms.getMap("fieldName1").getLongValue("name2").intValue());
      assertEquals(5, terms.getMap("fieldName2").getLongValue("name3").intValue());
      assertEquals(12, terms.getMap("fieldName2").getLongValue("name4").intValue());
    }
  }

  public void test_parseSpellcheck() {
    final NamedList<Object> response = new NamedList<>();
    {
      final NamedList<NamedList<Object>> spellcheck = new NamedList<>();
      response.add(SolrConstants.SPELLCHECK, spellcheck);
      final NamedList<Object> suggestions = new NamedList<>();
      spellcheck.add(SolrConstants.SUGGESTIONS, suggestions);
      final NamedList<Object> sugg = new NamedList<>();
      sugg.add(SolrConstants.START_OFFSET, 1);
      sugg.add(SolrConstants.END_OFFSET, 2);
      sugg.add(SolrConstants.ORIG_FREQ, 3);
      final List<String> alternatives = new ArrayList<>();
      alternatives.add("Oldtimer");
      alternatives.add("oldtimern");
      sugg.add("suggestion", alternatives);
      suggestions.add("Olktimer", sugg);
    }
    final QueryResponse queryResponse = new QueryResponse(response, new CloudSolrServer("localhost"));
    final ResponseParser parser = new ResponseParser(_factory.createRecord(), getSolrConfig(), ID_FIELD);
    {
      final Record result = parser.toRecord(queryResponse);
      final AnyMap suggestions =
        result.getMetadata().getMap(SolrParams.SOLR_PARAMETER_ATTRIBUTE).getMap(ResponseAccessor.RESPONSE)
          .getMap(SolrConstants.SPELLCHECK).getMap(SolrConstants.SUGGESTIONS);
      assertNotNull(suggestions);
      final AnyMap olktimer = suggestions.getMap("Olktimer");
      assertNotNull(olktimer);
      assertEquals(0, olktimer.getLongValue(SolrConstants.NUM_FOUND).intValue());
      assertEquals(1, olktimer.getLongValue(SolrConstants.START_OFFSET).intValue());
      assertEquals(2, olktimer.getLongValue(SolrConstants.END_OFFSET).intValue());
      assertEquals(3, olktimer.getLongValue(SolrConstants.ORIG_FREQ).intValue());
      final AnySeq suggestion = olktimer.getSeq(SolrConstants.SUGGESTION);
      assertEquals("Oldtimer", suggestion.getStringValue(0));
      assertEquals("oldtimern", suggestion.getStringValue(1));
    }
  }

  @SuppressWarnings("unchecked")
  public void test_parseSpellcheckExtendedResults() {
    final NamedList<Object> response = new NamedList<>();
    {
      final NamedList<NamedList<Object>> spellcheck = new NamedList<>();
      response.add(SolrConstants.SPELLCHECK, spellcheck);
      final NamedList<Object> suggestions = new NamedList<>();
      spellcheck.add(SolrConstants.SUGGESTIONS, suggestions);
      final NamedList<Object> sugg = new NamedList<>();
      sugg.add(SolrConstants.START_OFFSET, 1);
      sugg.add(SolrConstants.END_OFFSET, 2);
      sugg.add(SolrConstants.ORIG_FREQ, 3);
      @SuppressWarnings("rawtypes")
      final List<NamedList> alternatives = new ArrayList<>();
      @SuppressWarnings("rawtypes")
      final NamedList oldtimer = new NamedList<>();
      oldtimer.add(SolrConstants.WORD, "Oldtimer");
      oldtimer.add(SolrConstants.FREQ, 3);
      alternatives.add(oldtimer);
      @SuppressWarnings("rawtypes")
      final NamedList oltimern = new NamedList<>();
      oltimern.add(SolrConstants.WORD, "oldtimern");
      oltimern.add(SolrConstants.FREQ, 2);
      alternatives.add(oltimern);
      sugg.add(SolrConstants.SUGGESTION, alternatives);
      suggestions.add("Olktimer", sugg);
    }
    final QueryResponse queryResponse = new QueryResponse(response, new CloudSolrServer("localhost"));
    final ResponseParser parser = new ResponseParser(_factory.createRecord(), getSolrConfig(), ID_FIELD);
    {
      final Record result = parser.toRecord(queryResponse);
      final AnyMap suggestions =
        result.getMetadata().getMap(SolrParams.SOLR_PARAMETER_ATTRIBUTE).getMap(ResponseAccessor.RESPONSE)
          .getMap(SolrConstants.SPELLCHECK).getMap(SolrConstants.SUGGESTIONS);
      assertNotNull(suggestions);
      final AnyMap olktimer = suggestions.getMap("Olktimer");
      assertNotNull(olktimer);
      assertEquals(0, olktimer.getLongValue(SolrConstants.NUM_FOUND).intValue());
      assertEquals(1, olktimer.getLongValue(SolrConstants.START_OFFSET).intValue());
      assertEquals(2, olktimer.getLongValue(SolrConstants.END_OFFSET).intValue());
      assertEquals(3, olktimer.getLongValue(SolrConstants.ORIG_FREQ).intValue());
      final AnySeq suggestion = olktimer.getSeq(SolrConstants.SUGGESTION);
      final AnyMap oldtimer = suggestion.getMap(0);
      assertEquals("Oldtimer", oldtimer.getStringValue(SolrConstants.WORD));
      assertEquals(3, oldtimer.getLongValue(SolrConstants.FREQ).intValue());
      final AnyMap oldtimern = suggestion.getMap(1);
      assertEquals("oldtimern", oldtimern.getStringValue(SolrConstants.WORD));
      assertEquals(2, oldtimern.getLongValue(SolrConstants.FREQ).intValue());

    }
  }

  public void test_parseSpellcheckExtendedCollations() {
    final NamedList<Object> response = new NamedList<>();
    {
      final NamedList<NamedList<Object>> spellcheck = new NamedList<>();
      response.add(SolrConstants.SPELLCHECK, spellcheck);
      final NamedList<Object> suggestions = new NamedList<>();
      spellcheck.add(SolrConstants.SUGGESTIONS, suggestions);
      final NamedList<Object> expandedCollation = new NamedList<>();
      suggestions.add(SolrConstants.COLLATION, expandedCollation);
      expandedCollation.add(SolrConstants.COLLATION_QUERY, "q=query");
      expandedCollation.add(SolrConstants.HITS, 9);
      final NamedList<String> misspellingsAndCorrections = new NamedList<>();
      expandedCollation.add(SolrConstants.MISSPELLINGS_AND_CORRECTIONS, misspellingsAndCorrections);
      misspellingsAndCorrections.add("Olktimer", "Oldtimer");
      misspellingsAndCorrections.add("Oldtimern", "oldtimern");

    }
    final QueryResponse queryResponse = new QueryResponse(response, new CloudSolrServer("localhost"));
    final ResponseParser parser = new ResponseParser(_factory.createRecord(), getSolrConfig(), ID_FIELD);
    {
      final Record result = parser.toRecord(queryResponse);
      final AnyMap spellcheck =
        result.getMetadata().getMap(SolrParams.SOLR_PARAMETER_ATTRIBUTE).getMap(ResponseAccessor.RESPONSE)
          .getMap(SolrConstants.SPELLCHECK);
      assertNotNull(spellcheck);
      final AnyMap collations = spellcheck.getSeq(SolrConstants.COLLATIONS).getMap(0);
      assertEquals("q=query", collations.getStringValue(SolrConstants.COLLATION_QUERY));
      assertEquals(9, collations.getLongValue(SolrConstants.HITS).intValue());
      final AnyMap misspellingsAndCorrections = collations.getMap(SolrConstants.MISSPELLINGS_AND_CORRECTIONS);
      assertEquals("Oldtimer", misspellingsAndCorrections.getStringValue("Olktimer"));
      assertEquals("oldtimern", misspellingsAndCorrections.getStringValue("Oldtimern"));
    }
  }

  public void test_moreLikeThis() {
    final NamedList<Object> response = new NamedList<>();
    {
      final NamedList<SolrDocumentList> relatedDocuments = new NamedList<>();
      response.add(SolrConstants.MORE_LIKE_THIS, relatedDocuments);
      final SolrDocumentList documentList = new SolrDocumentList();
      documentList.setNumFound(2);
      documentList.setStart(1);
      final SolrDocument document1 = new SolrDocument();
      document1.setField(ID_FIELD, "doc1");
      final SolrDocument document2 = new SolrDocument();
      document2.setField(ID_FIELD, "doc2");
      documentList.add(document1);
      documentList.add(document2);
      relatedDocuments.add("docs", documentList);
    }
    final QueryResponse queryResponse = new QueryResponse(response, new CloudSolrServer("localhost"));
    final ResponseParser parser = new ResponseParser(_factory.createRecord(), getSolrConfig(), ID_FIELD);
    {
      final Record result = parser.toRecord(queryResponse);
      final AnyMap docs =
        result.getMetadata().getMap(SolrParams.SOLR_PARAMETER_ATTRIBUTE).getMap(ResponseAccessor.RESPONSE)
          .getMap(SolrConstants.MORE_LIKE_THIS).getMap("docs");
      assertNotNull(docs);
      assertEquals(2, docs.getLongValue(SolrConstants.NUM_FOUND).intValue());
      assertEquals(1, docs.getLongValue(SolrConstants.START).intValue());
      final AnySeq related = docs.getSeq(SolrConstants.RELATED);
      assertNotNull(related);
      assertEquals("doc1", related.getMap(0).getStringValue(ID_FIELD));
      assertEquals("doc2", related.getMap(1).getStringValue(ID_FIELD));
    }
  }

  public void test_parseCursorMark() {
    final NamedList<Object> response = new NamedList<>();
    final String cursorMarkNext = "thisIsTheNextCursorMark";
    {
      response.add(CursorMarkParams.CURSOR_MARK_NEXT, cursorMarkNext);
    }
    final QueryResponse queryResponse = new QueryResponse(response, new CloudSolrServer("localhost"));
    final ResponseParser parser = new ResponseParser(_factory.createRecord(), getSolrConfig(), ID_FIELD);
    {
      final Record result = parser.toRecord(queryResponse);
      final AnyMap responseMap =
        result.getMetadata().getMap(SolrParams.SOLR_PARAMETER_ATTRIBUTE).getMap(ResponseAccessor.RESPONSE);
      assertNotNull(responseMap);
      assertEquals(cursorMarkNext, responseMap.getStringValue(SolrConstants.NEXT_CURSOR_MARK));
    }
  }

  public void test_parseDebug() {
    final NamedList<Object> response = new NamedList<>();
    {
      final NamedList<Object> debug = new NamedList<>();
      response.add(SolrConstants.DEBUG, debug);
      debug.add("key1", "value1");
      debug.add("key2", "value2");
      final NamedList<String> explain = new NamedList<>();
      debug.add("explain", explain);
      explain.add("explain", "this");
    }
    final QueryResponse queryResponse = new QueryResponse(response, new CloudSolrServer("localhost"));
    final ResponseParser parser = new ResponseParser(_factory.createRecord(), getSolrConfig(), ID_FIELD);
    {
      final Record result = parser.toRecord(queryResponse);
      final AnyMap debug =
        result.getMetadata().getMap(SolrParams.SOLR_PARAMETER_ATTRIBUTE).getMap(ResponseAccessor.RESPONSE)
          .getMap(SolrConstants.DEBUG);
      assertNotNull(debug);
      assertEquals("value1", debug.getStringValue("key1"));
      assertEquals("value2", debug.getStringValue("key2"));
      final AnyMap explain = debug.getMap("explain");
      assertEquals("this", explain.getStringValue("explain"));
    }
  }

  public void test_parseStats() {
    final NamedList<Object> response = new NamedList<>();
    {
      final NamedList<Object> stats = new NamedList<>();
      response.add(SolrConstants.STATS, stats);
      final NamedList<NamedList<Object>> statsFields = new NamedList<>();
      stats.add("stats_fields", statsFields);
      final NamedList<Object> statsFieldsEntry = new NamedList<>();
      statsFields.add("statsFieldEntry", statsFieldsEntry);
      statsFieldsEntry.add(SolrConstants.MIN, -1);
      statsFieldsEntry.add(SolrConstants.MAX, 2);
      statsFieldsEntry.add(SolrConstants.COUNT, new Long(5));
      statsFieldsEntry.add(SolrConstants.MISSING, new Long(7));
      statsFieldsEntry.add(SolrConstants.SUM, 42);
      statsFieldsEntry.add(SolrConstants.MEAN, 9);
      statsFieldsEntry.add(SolrConstants.STDDEV, 2.4);
      final NamedList<Object> facets = new NamedList<>();
      statsFieldsEntry.add(SolrConstants.FACETS, facets);
      final NamedList<NamedList<Object>> field = new NamedList<>();
      facets.add("author", field);
      final NamedList<Object> author = new NamedList<>();
      field.add("values", author);
      author.add(SolrConstants.MIN, -1);
      author.add(SolrConstants.MAX, 2);
      author.add(SolrConstants.COUNT, new Long(5));
      author.add(SolrConstants.MISSING, new Long(7));
      author.add(SolrConstants.SUM, 42);
      author.add(SolrConstants.MEAN, 9);
      author.add(SolrConstants.STDDEV, 2.4);

    }
    final QueryResponse queryResponse = new QueryResponse(response, new CloudSolrServer("localhost"));
    final ResponseParser parser = new ResponseParser(_factory.createRecord(), getSolrConfig(), ID_FIELD);
    {
      final Record result = parser.toRecord(queryResponse);
      final AnyMap statsFieldEntry =
        result.getMetadata().getMap(SolrParams.SOLR_PARAMETER_ATTRIBUTE).getMap(ResponseAccessor.RESPONSE)
          .getMap(SolrConstants.STATS).getMap("statsFieldEntry");
      assertNotNull(statsFieldEntry);
      assertEquals(-1, statsFieldEntry.getLongValue(SolrConstants.MIN).intValue());
      assertEquals(2, statsFieldEntry.getLongValue(SolrConstants.MAX).intValue());
      assertEquals(5, statsFieldEntry.getLongValue(SolrConstants.COUNT).intValue());
      assertEquals(7, statsFieldEntry.getLongValue(SolrConstants.MISSING).intValue());
      assertEquals(42, statsFieldEntry.getLongValue(SolrConstants.SUM).intValue());
      assertEquals(9, statsFieldEntry.getLongValue(SolrConstants.MEAN).intValue());
      assertEquals(2.4, statsFieldEntry.getDoubleValue(SolrConstants.STDDEV).doubleValue());
      final AnyMap authorFacet = statsFieldEntry.getMap(SolrConstants.FACETS).getMap("author");
      assertEquals(-1, authorFacet.getLongValue(SolrConstants.MIN).intValue());
      assertEquals(2, authorFacet.getLongValue(SolrConstants.MAX).intValue());
      assertEquals(5, authorFacet.getLongValue(SolrConstants.COUNT).intValue());
      assertEquals(7, authorFacet.getLongValue(SolrConstants.MISSING).intValue());
      assertEquals(42, authorFacet.getLongValue(SolrConstants.SUM).intValue());
      assertEquals(9, authorFacet.getLongValue(SolrConstants.MEAN).intValue());
      assertEquals(2.4, authorFacet.getDoubleValue(SolrConstants.STDDEV).doubleValue());
    }
  }

  public void test_parseHighlighting() {
    final NamedList<Object> response = new NamedList<>();
    {
      final NamedList<Object> highlighting = new NamedList<>();
      response.add("highlighting", highlighting);
      final NamedList<List<String>> doc = new NamedList<>();
      highlighting.add("document1", doc);
      final List<String> values = new ArrayList<>();
      doc.add("values", values);
      values.add("highlight1");
      values.add("highlight2");

      final SolrDocumentList solrDocumentList = new SolrDocumentList();
      solrDocumentList.setNumFound(1);
      final SolrDocument document1 = new SolrDocument();
      document1.setField(ID_FIELD, "document1");
      solrDocumentList.add(document1);
      response.add(ResponseAccessor.RESPONSE, solrDocumentList);

    }
    final QueryResponse queryResponse = new QueryResponse(response, new CloudSolrServer("localhost"));
    final ResponseParser parser = new ResponseParser(_factory.createRecord(), getSolrConfig(), ID_FIELD);
    {
      final Record result = parser.toRecord(queryResponse);
      assertEquals(1, result.getMetadata().getLongValue(SearchResultConstants.COUNT).intValue());
      final AnyMap record = result.getMetadata().getSeq(SearchResultConstants.RECORDS).getMap(0);
      assertEquals("document1", record.getStringValue(ID_FIELD));
      final AnySeq text =
        record.getMap(SearchResultConstants.HIGHLIGHT).getMap("values")
          .getSeq(SearchResultConstants.HIGHLIGHT_TEXT);
      assertNotNull(text);
      assertEquals("highlight1", text.getStringValue(0));
      assertEquals("highlight2", text.getStringValue(1));
    }
  }

}
