package eu.dnetlib.broker.utils;

import java.time.Duration;
import java.time.Instant;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import eu.dnetlib.broker.common.elasticsearch.Event;
import eu.dnetlib.broker.common.topics.TopicType;
import eu.dnetlib.broker.common.topics.TopicTypeRepository;

public class EventVerifier implements Predicate<Event> {

	private final TopicTypeRepository topicTypeRepo;
	private final long MAX_DELAY = 30000; // 30 seconds
	private Instant last = Instant.EPOCH;
	private List<Predicate<Event>> validators = new ArrayList<>();

	private static final Log log = LogFactory.getLog(EventVerifier.class);

	public EventVerifier(final TopicTypeRepository topicTypeRepo) {
		this.topicTypeRepo = topicTypeRepo;
	}

	@Override
	public boolean test(final Event event) {
		if (event == null || StringUtils.isBlank(event.getProducerId())) { return false; }

		// TODO: La lista delle topicTypes deve essere in funzione del producer
		final Instant now = Instant.now();
		if (Duration.between(this.last, now).toMillis() > this.MAX_DELAY) {
			log.info("Updating the list of topic regex");

			final Iterable<TopicType> iter = this.topicTypeRepo.findAll();
			this.validators = StreamSupport.stream(iter.spliterator(), false)
				.map(TopicType::asValidator)
				.collect(Collectors.toList());
		}

		try {
			return this.validators.stream().anyMatch(p -> p.test(event));
		} catch (final Throwable e) {
			return false;
		} finally {
			this.last = now;
		}
	}

}
