package eu.dnetlib.is.vocabulary;

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

import javax.transaction.Transactional;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import eu.dnetlib.data.is.vocabulary.model.Vocabulary;
import eu.dnetlib.data.is.vocabulary.model.VocabularyTerm;
import eu.dnetlib.data.is.vocabulary.model.VocabularyTermPK;
import eu.dnetlib.data.is.vocabulary.repository.VocabularyRepository;
import eu.dnetlib.data.is.vocabulary.repository.VocabularyTermRepository;
import eu.dnetlib.is.errors.InformationServiceException;

@Service
public class VocabularyService {

	@Autowired
	private VocabularyRepository vocabularyRepository;

	@Autowired
	private VocabularyTermRepository vocabularyTermRepository;

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

	public List<Vocabulary> listVocs() {
		return vocabularyRepository.findAll()
			.stream()
			.sorted((v1, v2) -> StringUtils.compareIgnoreCase(v1.getId(), v2.getId()))
			.collect(Collectors.toList());
	}

	public Vocabulary getVoc(final String vocabulary) throws InformationServiceException {
		return vocabularyRepository.findById(vocabulary).orElseThrow(() -> new InformationServiceException("Vocabulary not found"));
	}

	@Transactional
	public void deleteVocs(final String... ids) {
		for (final String id : ids) {
			vocabularyRepository.deleteById(id);
		}
	}

	public void saveVoc(final Vocabulary voc) {
		log.info("Saving vocabulary: " + voc);
		vocabularyRepository.save(voc);
	}

	public Iterable<VocabularyTerm> listTerms(final String vocabulary) {
		return vocabularyTermRepository.findByVocabularyOrderByCode(vocabulary);
	}

	@Transactional
	public void saveTerms(final String vocabulary, final VocabularyTerm... terms) {
		for (final VocabularyTerm t : terms) {
			t.setVocabulary(vocabulary);
			vocabularyTermRepository.save(t);
		}
	}

	@Transactional
	public void deleteTerms(final String vocabulary, final String... terms) {
		for (final String t : terms) {
			final VocabularyTermPK pk = new VocabularyTermPK();
			pk.setCode(t);
			pk.setVocabulary(vocabulary);
			vocabularyTermRepository.deleteById(pk);
		}
	}

}
