package eu.dnetlib.broker.common.elasticsearch;

import java.util.List;
import java.util.stream.Collectors;

import org.elasticsearch.action.search.SearchType;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.Aggregations;
import org.elasticsearch.search.aggregations.bucket.terms.ParsedStringTerms;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.elasticsearch.core.ElasticsearchOperations;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.stereotype.Component;

import eu.dnetlib.broker.common.properties.ElasticSearchProperties;

@Component
public class EventStatsManager {

	@Autowired
	private ElasticsearchOperations esOperations;

	@Autowired
	private ElasticSearchProperties elasticSearchProperties;

	public class BrowseEntry {

		private final String value;
		private final long count;

		public BrowseEntry(final String value, final long count) {
			this.value = value;
			this.count = count;
		}

		public String getValue() {
			return value;
		}

		public long getCount() {
			return count;
		}

	}

	public List<BrowseEntry> browseTopics() {

		final String term = "topic.keyword";

		final NativeSearchQuery searchQuery = new NativeSearchQueryBuilder()
			.withQuery(QueryBuilders.matchAllQuery())
			.withSearchType(SearchType.DEFAULT)
			.addAggregation(AggregationBuilders.terms(term).field(term).size(1000).minDocCount(1))
			.build();

		final SearchHits<Event> hits = esOperations.search(searchQuery, Event.class, IndexCoordinates.of(elasticSearchProperties.getEventsIndexName()));

		final Aggregations aggregations = hits.getAggregations();

		return ((ParsedStringTerms) aggregations.asMap().get(term)).getBuckets()
			.stream()
			.map(b -> new BrowseEntry(b.getKeyAsString(), b.getDocCount()))
			.collect(Collectors.toList());

	}

}
