package eu.dnetlib.is.resources;

import java.util.Date;
import java.util.List;
import java.util.UUID;
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 org.springframework.web.bind.annotation.PathVariable;

import eu.dnetlib.data.is.resource.model.SimpleResource;
import eu.dnetlib.data.is.resource.repository.SimpleResourceRepository;
import eu.dnetlib.is.errors.InformationServiceException;
import eu.dnetlib.is.util.ResourceValidator;

@Service
public class SimpleResourceService {

	@Autowired
	private SimpleResourceRepository simpleResourceRepository;

	@Autowired
	private ResourceValidator resourceValidator;

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

	public SimpleResource getMetadata(final String id) throws InformationServiceException {
		return simpleResourceRepository.findById(id).orElseThrow(() -> new InformationServiceException("Id not found"));
	}

	public String getContent(final String id) throws InformationServiceException {
		return simpleResourceRepository.findContentById(id).orElseThrow(() -> new InformationServiceException("Id not found"));
	}

	public String getContentType(final String id) throws InformationServiceException {
		return simpleResourceRepository.findContentTypeById(id).orElseThrow(() -> new InformationServiceException("Id not found"));
	}

	public List<SimpleResource> listResources(final String type) {
		return simpleResourceRepository.findByType(type)
			.stream()
			.sorted((r1, r2) -> StringUtils.compareIgnoreCase(r1.getName(), r2.getName()))
			.collect(Collectors.toList());
	}

	public void deleteResource(@PathVariable final String id) {
		log.info("Deleting resource: " + id);
		simpleResourceRepository.deleteById(id);
	}

	@Transactional
	public SimpleResource saveNewResource(final String name,
		final String type,
		final String description,
		final String content) throws InformationServiceException {

		resourceValidator.validate(type, content);

		final Date now = new Date();

		final SimpleResource res = new SimpleResource();
		res.setId(UUID.randomUUID().toString());
		res.setName(name);
		res.setType(type);
		res.setDescription(description);
		res.setCreationDate(now);
		res.setModificationDate(now);

		simpleResourceRepository.save(res);
		simpleResourceRepository.setContentById(res.getId(), content);

		return res;
	}

	@Transactional
	public void saveMetadata(final String id, final SimpleResource r) throws InformationServiceException {
		if (simpleResourceRepository.existsById(id)) {
			r.setId(id);
			simpleResourceRepository.save(r);
		} else {
			throw new InformationServiceException("Resource not found");
		}
	}

	@Transactional
	public void saveContent(final String id, final String content) throws InformationServiceException {
		final SimpleResource res = simpleResourceRepository.findById(id).orElseThrow(() -> new InformationServiceException("Resource not found"));

		resourceValidator.validate(res.getType(), content);

		simpleResourceRepository.setContentById(id, content);

	}
}
