package eu.dnetlib.broker.openaire;

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

import org.apache.commons.lang3.StringUtils;

import eu.dnetlib.broker.common.subscriptions.ConditionOperator;
import eu.dnetlib.broker.common.subscriptions.ConditionParams;
import eu.dnetlib.broker.common.subscriptions.MapCondition;
import eu.dnetlib.broker.common.utils.MapValueType;

public class AdvQueryObject {

	private String datasource = "";
	private String topic = "";
	private List<String> titles = new ArrayList<>();
	private List<String> subjects = new ArrayList<>();
	private List<String> authors = new ArrayList<>();
	private List<Range> dates = new ArrayList<>();
	private Range trust = new Range("0", "1");

	public AdvQueryObject() {}

	public AdvQueryObject(final String datasource, final String topic, final List<String> titles, final List<String> subjects, final List<String> authors,
		final List<Range> dates, final Range trust) {
		super();
		this.datasource = datasource;
		this.topic = topic;
		this.titles = titles;
		this.subjects = subjects;
		this.authors = authors;
		this.dates = dates;
		this.trust = trust;
	}

	public String getDatasource() {
		return this.datasource;
	}

	public void setDatasource(final String datasource) {
		this.datasource = datasource;
	}

	public String getTopic() {
		return this.topic;
	}

	public void setTopic(final String topic) {
		this.topic = topic;
	}

	public List<String> getTitles() {
		return this.titles;
	}

	public void setTitles(final List<String> titles) {
		this.titles = titles;
	}

	public List<String> getSubjects() {
		return this.subjects;
	}

	public void setSubjects(final List<String> subjects) {
		this.subjects = subjects;
	}

	public List<String> getAuthors() {
		return this.authors;
	}

	public void setAuthors(final List<String> authors) {
		this.authors = authors;
	}

	public List<Range> getDates() {
		return this.dates;
	}

	public void setDates(final List<Range> dates) {
		this.dates = dates;
	}

	public Range getTrust() {
		return this.trust;
	}

	public void setTrust(final Range trust) {
		this.trust = trust;
	}

	public List<MapCondition> asListOfConditions() {
		final List<MapCondition> list = new ArrayList<>();

		final List<ConditionParams> list_dates = this.dates.stream()
			.filter(Range::isValid)
			.map(d -> new ConditionParams(d.getMin(), d.getMax()))
			.collect(Collectors.toList());

		final List<ConditionParams> list_titles = this.titles.stream()
			.filter(StringUtils::isNotBlank)
			.map(t -> new ConditionParams(t, null))
			.collect(Collectors.toList());

		final List<ConditionParams> list_authors = this.authors.stream()
			.filter(StringUtils::isNotBlank)
			.map(aut -> new ConditionParams(aut, null))
			.collect(Collectors.toList());

		final List<ConditionParams> list_subjects = this.subjects.stream()
			.filter(StringUtils::isNotBlank)
			.map(s -> new ConditionParams(s, null))
			.collect(Collectors.toList());

		if (StringUtils.isNotBlank(this.datasource)) {
			list.add(new MapCondition("targetDatasourceName", MapValueType.STRING, ConditionOperator.EXACT,
				Arrays.asList(new ConditionParams(this.datasource, null))));
		}
		if (this.trust.isValid()) {
			list.add(new MapCondition("trust", MapValueType.FLOAT, ConditionOperator.RANGE,
				Arrays.asList(new ConditionParams(this.trust.getMin(), this.trust.getMax()))));
		}
		if (!list_dates.isEmpty()) {
			list.add(new MapCondition("targetDateofacceptance", MapValueType.DATE, ConditionOperator.RANGE, list_dates));
		}
		if (!list_titles.isEmpty()) {
			list.add(new MapCondition("targetResultTitle", MapValueType.LIST_STRING, ConditionOperator.MATCH_ALL, list_titles));
		}
		if (!list_authors.isEmpty()) {
			list.add(new MapCondition("targetAuthors", MapValueType.LIST_STRING, ConditionOperator.MATCH_ALL, list_authors));
		}
		if (!list_subjects.isEmpty()) {
			list.add(new MapCondition("targetSubjects", MapValueType.LIST_STRING, ConditionOperator.MATCH_ALL, list_subjects));
		}

		return list;
	}

}
