/*
 * 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.vw.services.infrastructure.remote.admin;

import org.apache.commons.lang3.exception.ExceptionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import retrofit2.Retrofit;

import javax.annotation.PostConstruct;
import javax.ejb.Stateless;
import javax.inject.Inject;

import com.scytl.products.oscore.logging.api.domain.Level;
import com.scytl.products.oscore.logging.api.domain.LogContent;
import com.scytl.products.oscore.logging.api.writer.SecureLoggingWriter;
import com.scytl.products.ov.commons.beans.exceptions.ResourceNotFoundException;
import com.scytl.products.ov.commons.beans.exceptions.VoterInformationRepositoryImplException;
import com.scytl.products.ov.commons.infrastructure.exception.OvCommonsInfrastructureException;
import com.scytl.products.ov.commons.infrastructure.remote.client.RestClientConnectionManager;
import com.scytl.products.ov.commons.infrastructure.remote.client.RetrofitConsumer;
import com.scytl.products.ov.commons.logging.I18nLoggerMessages;
import com.scytl.products.ov.commons.tracking.TrackIdInstance;
import com.scytl.products.ov.commons.util.PropertiesFileReader;
import com.scytl.products.ov.vw.infrastructure.log.InternalEvents;
import com.scytl.products.ov.vw.infrastructure.log.VotingWorkflowLogConstants;
import com.scytl.products.ov.vw.services.domain.model.information.VoterInformation;
import com.scytl.products.ov.vw.services.domain.model.information.VoterInformationRepository;

/**
 * The Class VoterInformationRepositoryImpl.
 */
@Stateless(name = "vw-VoterInformationRepositoryImpl")
public class VoterInformationRepositoryImpl implements VoterInformationRepository {

	/**
	 * The properties file reader.
	 */
	private static final PropertiesFileReader PROPERTIES = PropertiesFileReader.getInstance();

	/** The Constant URI_VOTER_MATERIAL. */
	private static final String URI_VOTER_MATERIAL = System.getProperty("VOTER_MATERIAL_CONTEXT_URL");

	/** The Constant VOTER_INFORMATION_PATH. */
	private static final String VOTER_INFORMATION_PATH = PROPERTIES.getPropertyValue("VOTER_INFORMATION_PATH");

	/** The track id. */
	@Inject
	private TrackIdInstance trackId;

	private static final Logger LOG = LoggerFactory.getLogger("std");

	@Inject
	private SecureLoggingWriter secureLoggerWriter;

	private static final I18nLoggerMessages I18N = I18nLoggerMessages.getInstance();

	/** The voter material admin client. */
	private VoterMaterialAdminClient voterMaterialAdminClient;

	/**
	 * Intialize clients.
	 */
	@PostConstruct
	public void intializeClients() {

        Retrofit client;
        try {
            client = RestClientConnectionManager.getInstance().getRestClient(URI_VOTER_MATERIAL);

        } catch (OvCommonsInfrastructureException e) {
            LOG.error("Error trying to obtain a REST client.");
            throw new VoterInformationRepositoryImplException("Error trying to obtain a REST client.", e);
        }

        voterMaterialAdminClient = client.create(VoterMaterialAdminClient.class);
	}

	/**
	 * Gets the by tenant id election event id voting card id.
	 *
	 * @param tenantId the tenant id
	 * @param electionEventId the election event id
	 * @param votingCardId the voting card id
	 * @return the by tenant id election event id voting card id
	 * @throws ResourceNotFoundException the resource not found exception
	 */
	@Override
	public VoterInformation getByTenantIdElectionEventIdVotingCardId(final String tenantId, final String electionEventId,
			final String votingCardId) throws ResourceNotFoundException {

		LOG.info(I18N.getMessage("VoterInformationRepositoryImpl.getByTenantIdElectionEventIdVotingCardId"), tenantId,
			electionEventId, votingCardId);

		try {
			VoterInformation voterInformation = RetrofitConsumer.processResponse(voterMaterialAdminClient.getVoterInformations(trackId.getTrackId(),
				VOTER_INFORMATION_PATH, tenantId, electionEventId, votingCardId));

			LOG.info(I18N.getMessage("VoterInformationRepositoryImpl.getByTenantIdElectionEventIdVotingCardId.found"),
				tenantId, electionEventId, votingCardId);

			// voting card id data found
			secureLoggerWriter.log(Level.INFO,
				new LogContent.LogContentBuilder().logEvent(InternalEvents.VOTER_INFORMATION_FOUND)
					.objectId(votingCardId).user(votingCardId).electionEvent(electionEventId)
					.additionalInfo(VotingWorkflowLogConstants.INFO_TRACK_ID, trackId.getTrackId())
					.createLogInfo());

			return voterInformation;

		} catch (ResourceNotFoundException e) {
			LOG.error(I18N.getMessage("VoterInformationRepositoryImpl.getByTenantIdElectionEventIdVotingCardId.notFound"),
				tenantId, electionEventId, votingCardId);

			// voting card id data not found
			secureLoggerWriter.log(Level.ERROR,
				new LogContent.LogContentBuilder().logEvent(InternalEvents.VOTER_INFORMATION_NOT_FOUND)
					.objectId(votingCardId).user(votingCardId).electionEvent(electionEventId)
					.additionalInfo(VotingWorkflowLogConstants.INFO_TRACK_ID, trackId.getTrackId())
					.additionalInfo(VotingWorkflowLogConstants.INFO_ERR_DESC,
						"Voter Information not found: " + ExceptionUtils.getRootCauseMessage(e))
					.createLogInfo());

			throw e;
		}
	}

}
