
package eu.dnetlib.dhp.contextpropagation.model;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;

import org.apache.avro.generic.GenericData;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

import eu.dnetlib.dhp.oa.graph.dump.SaveCommunityMap;
import eu.dnetlib.dhp.provision.scholix.summary.SchemeValue;
import eu.dnetlib.dhp.schema.dump.oaf.GeoLocation;

public class EnrichedEntries implements Serializable {
	private static final Logger log = LoggerFactory.getLogger(EnrichedEntries.class);
	private String scholixId;
	private String openAireId;
	private List<String> title;
	private List<String> description;
	private List<SchemeValue> subject;

	public String getScholixId() {
		return scholixId;
	}

	public void setScholixId(String scholixId) {
		this.scholixId = scholixId;
	}

	public List<String> getTitle() {
		return title;
	}

	public void setTitle(List<String> title) {
		this.title = title;
	}

	public List<String> getDescription() {
		return description;
	}

	public void setDescription(List<String> description) {
		this.description = description;
	}

	public List<SchemeValue> getSubject() {
		return subject;
	}

	public void setSubject(List<SchemeValue> subject) {
		this.subject = subject;
	}

	public String getOpenAireId() {
		return openAireId;
	}

	public void setOpenAireId(String openAireId) {
		this.openAireId = openAireId;
	}

	public EnrichedEntries mergeWith(EnrichedEntries ee) throws JsonProcessingException {
		if(ee == null){
			throw new RuntimeException("ERROR: ee is null");
		}

		if (scholixId == null)
			scholixId = ee.scholixId;

		if (openAireId == null)
			openAireId = ee.openAireId;

		try {

			Optional
				.ofNullable(ee.getDescription())
				.ifPresent(
					d -> d
						.stream()
						.filter(Objects::nonNull)
						.forEach(this::mergeAbstract));

			Optional
				.ofNullable((ee.getTitle()))
				.ifPresent(
					t -> t
						.stream()
						.filter(Objects::nonNull)
						.forEach(this::mergeTitle));

			Optional
				.ofNullable(ee.getSubject())
				.ifPresent(
					s -> s
						.stream()
						.filter(Objects::nonNull)
						.forEach(this::mergeSubject));
		} catch (Exception e) {
			throw new RuntimeException("Error in merging " + ee.getScholixId(), e);
		}

		return this;
	}

	private void mergeSubject(SchemeValue sbj) {
		if (subject == null) {
			subject = new ArrayList<>();
		}
		for (SchemeValue s : subject) {
			if (s.getValue().equals(sbj.getValue())) {
				return;
			}
		}
		subject.add(sbj);
	}

	private void mergeAbstract(String dex) {
		if (description == null) {
			description = new ArrayList<>();
		}
		merge(dex, description);

	}

	private void mergeTitle(String t) {
		if (title == null) {
			title = new ArrayList<>();
		}
		merge(t, title);

	}

	private void merge(String st, List<String> lst) {
		for (String d : lst) {
			if (d.equals(st))
				return;
		}
		lst.add(st);
	}
}
