/*
 * Copyright 2018 Scytl Secure Electronic Voting SA
 *
 * All rights reserved
 *
 * See our extended copyright notice in *file 'Copyright.txt' which is part of this source code package
 */
package com.scytl.products.ov.kt.services.infrastructure.persistence.impl;

import javax.ejb.Stateless;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;
import javax.persistence.NoResultException;
import javax.persistence.TypedQuery;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.scytl.products.ov.commons.beans.exceptions.DuplicateEntryException;
import com.scytl.products.ov.commons.beans.exceptions.EntryPersistenceException;
import com.scytl.products.ov.commons.beans.exceptions.ResourceNotFoundException;
import com.scytl.products.ov.commons.infrastructure.persistence.BaseRepositoryImpl;
import com.scytl.products.ov.kt.domain.model.electionevent.ElectionEventTranslation;
import com.scytl.products.ov.kt.domain.model.electionevent.ElectionEventTranslationRepository;

/**
 * Implementation of the repository with jpa
 */
@Stateless
public class ElectionEventTranslationRepositoryImpl extends BaseRepositoryImpl<ElectionEventTranslation, Integer>
		implements ElectionEventTranslationRepository {

	private static final String PARAMETER_TENANT_ID = "tenantId";

	private static final String PARAMETER_ALIAS = "alias";

	private static final String PARAMETER_ELECTION_EVENT_ID = "electionEventId";

    private static final Logger LOG = LoggerFactory.getLogger(ElectionEventTranslationRepositoryImpl.class);

	/**
	 * @see com.scytl.products.ov.kt.domain.model.electionevent.ElectionEventTranslationRepository#findByAlias(java.lang.String,
	 *      java.lang.String)
	 */
	@Override
	public ElectionEventTranslation findByAlias(String tenantId, String alias) throws ResourceNotFoundException {
		TypedQuery<ElectionEventTranslation> query = entityManager.createQuery(
			"SELECT e FROM ElectionEventTranslation e WHERE e.tenantId = :tenantId AND e.alias = :alias",
			ElectionEventTranslation.class);
		query.setParameter(PARAMETER_TENANT_ID, tenantId);
		query.setParameter(PARAMETER_ALIAS, alias);
		try {
			return query.getSingleResult();
		} catch (NoResultException e) {
			throw new ResourceNotFoundException("Election event not found", e);
		}
	}

	/**
	 * @see com.scytl.products.ov.kt.domain.model.electionevent.ElectionEventTranslationRepository#save(java.io.InputStream)
	 */
	@Override
	@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
	public void saveVOrUpdateEET(ElectionEventTranslation ee) {
		try {
			save(ee);
		} catch (DuplicateEntryException e) {
			LOG.error("Duplicate entry found, but continue updating record", e);
			updateEET(ee);
		}
	}

	@Override
	public ElectionEventTranslation findByElectionEventId(final String tenantId, final String electionEventId) throws ResourceNotFoundException {
		TypedQuery<ElectionEventTranslation> query = entityManager.createQuery(
			"SELECT e FROM ElectionEventTranslation e WHERE e.tenantId = :tenantId AND e.electionEventId = :electionEventId",
			ElectionEventTranslation.class);
		query.setParameter(PARAMETER_TENANT_ID, tenantId);
		query.setParameter(PARAMETER_ELECTION_EVENT_ID, electionEventId);
		try {
			return query.getSingleResult();
		} catch (NoResultException e) {
			throw new ResourceNotFoundException("Election event not found", e);
		}
	}

	@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
	private void updateEET(ElectionEventTranslation ee) {
		try {
			update(ee);
		} catch (EntryPersistenceException e) {
			LOG.error("Error updating, continue with next record", e);
		}
	}
}
