/**
 * Copyright (c) 2000-2017 Liferay, Inc. All rights reserved.
 *
 * The contents of this file are subject to the terms of the Liferay Enterprise
 * pSubscription License ("License"). You may not use this file except in
 * compliance with the License. You can obtain a copy of the License by
 * contacting Liferay, Inc. See the License for the specific language governing
 * permissions and limitations under the License, including but not limited to
 * distribution rights of the Software.
 *
 *
 *
 */

package com.liferay.portal.search.facet;

import com.browseengine.bobo.api.BrowseFacet;

import com.liferay.portal.kernel.search.Document;
import com.liferay.portal.kernel.search.Field;
import com.liferay.portal.kernel.search.facet.Facet;
import com.liferay.portal.kernel.search.facet.collector.FacetCollector;
import com.liferay.portal.kernel.search.facet.collector.TermCollector;
import com.liferay.portal.search.BoboTermCollector;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author Bryan Engler
 * @author André de Oliveira
 */
public class FacetDiscounter {

	public FacetDiscounter(Facet facet) {
		_facet = facet;
	}

	public void discount(Collection<Document> documents) {
		for (Document document : documents) {
			_exclude(document);
		}

		_decrement();
	}

	private void _decrement() {
		if (_excludedTermsMap.isEmpty()) {
			return;
		}

		FacetCollector facetCollector = _facet.getFacetCollector();

		List<TermCollector> termCollectors = facetCollector.getTermCollectors();

		List<TermCollector> newTermCollectors = new ArrayList<TermCollector>(
			termCollectors.size());

		for (TermCollector termCollector : termCollectors) {
			String term = termCollector.getTerm();

			int exclusions = _getExclusions(term);

			int frequency = termCollector.getFrequency() - exclusions;

			if (frequency > 0) {
				newTermCollectors.add(
					new BoboTermCollector(new BrowseFacet(term, frequency)));
			}
		}

		_facet.setFacetCollector(
			new SimpleFacetCollector(
				facetCollector.getFieldName(), newTermCollectors));
	}

	private void _exclude(Document document) {
		Field field = document.getField(_facet.getFieldName());

		if (field == null) {
			return;
		}

		List<String> terms = _findTermsOfField(field);

		for (String term : terms) {
			_exclude(term);
		}
	}

	private void _exclude(String term) {
		int exclusions = _getExclusions(term);

		_excludedTermsMap.put(term, exclusions + 1);
	}

	private List<String> _findTermsOfField(Field field) {
		FacetCollector facetCollector = _facet.getFacetCollector();

		List<TermCollector> termCollectors = facetCollector.getTermCollectors();

		List<String> terms = new ArrayList<String>();

		for (TermCollector termCollector : termCollectors) {
			terms.add(termCollector.getTerm());
		}

		List<String> termsOfField = new ArrayList<String>();

		for (String term : terms) {
			if (FacetBucketUtil.isFieldInBucket(field, term, _facet)) {
				termsOfField.add(term);
			}
		}

		return termsOfField;
	}

	private int _getExclusions(String term) {
		Integer exclusions = _excludedTermsMap.get(term);

		if (exclusions != null) {
			return exclusions;
		}

		return 0;
	}

	private final Map<String, Integer> _excludedTermsMap =
		new HashMap<String, Integer>();
	private final Facet _facet;

}