/*
 * 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.votingcard.VotingCardTranslation;
import com.scytl.products.ov.kt.domain.model.votingcard.VotingCardTranslationRepository;

/**
 * Implementation of the repository with jpa
 */
@Stateless
public class VotingCardTranslationRepositoryImpl extends BaseRepositoryImpl<VotingCardTranslation, Integer>
		implements VotingCardTranslationRepository {

	private static final String PARAMETER_TENANT_ID = "tenantId";

	private static final String PARAMETER_ELECTION_EVENT_ID = "electionEventId";

	private static final String PARAMETER_ALIAS = "alias";

	private static final Logger LOG = LoggerFactory.getLogger(VotingCardTranslationRepositoryImpl.class);
	
	/**
	 * @see com.scytl.products.ov.kt.domain.model.electionevent.ElectionEventTranslationRepository#findByAlias(java.lang.String,
	 *      java.lang.String)
	 */
	@Override
	public VotingCardTranslation findByAlias(final String tenantId, final String electionEventId, final String alias)
			throws ResourceNotFoundException {
		final TypedQuery<VotingCardTranslation> query = entityManager.createQuery(
			"SELECT e FROM VotingCardTranslation e WHERE e.tenantId = :tenantId AND e.electionEventId = :electionEventId AND e.alias = :alias",
			VotingCardTranslation.class);
		query.setParameter(PARAMETER_TENANT_ID, tenantId);
		query.setParameter(PARAMETER_ELECTION_EVENT_ID, electionEventId);
		query.setParameter(PARAMETER_ALIAS, alias);
		try {
			return query.getSingleResult();
		} catch (final NoResultException e) {
			throw new ResourceNotFoundException("Voting card not found", e);
		}
	}

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

	@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
	private void updateVCT(final VotingCardTranslation vc) {
		try {
			update(vc);
		} catch (final EntryPersistenceException e) {
			LOG.error("Error updating, continue with next record", e);
		}
	}
}
