/*
 * 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;

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

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.ApplicationException;
import com.scytl.products.ov.commons.beans.exceptions.ResourceNotFoundException;
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.VotingWorkflowLogConstants;
import com.scytl.products.ov.vw.infrastructure.log.VotingWorkflowLogEvents;
import com.scytl.products.ov.vw.services.domain.model.authentication.CredentialInformation;
import com.scytl.products.ov.vw.services.domain.model.authentication.CredentialInformationRepository;

/**
 * Implementation of the AuthenticationInformationRepository using a REST
 * client.
 */
@Stateless
public class CredentialInformationRepositoryImpl implements CredentialInformationRepository {

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

    // The path to the resource authentication information.
    private static final String AUTHENTICATION_INFORMATION_PATH =
        PROPERTIES.getPropertyValue("AUTHENTICATION_INFORMATION_PATH");

    // Instance of the I18N logger messages
    private static final I18nLoggerMessages I18N = I18nLoggerMessages.getInstance();

    // Instance of the secure logger
    private static final Logger LOG = LoggerFactory.getLogger("std");

    @Inject
    private TrackIdInstance trackId;

    @Inject
    private SecureLoggingWriter secureLoggerWriter;

    private AuthenticationClient authenticationClient;

    @Inject
    CredentialInformationRepositoryImpl(final AuthenticationClient authenticationClient) {
        this.authenticationClient = authenticationClient;
    }

    /**
     * Searches the associated authentication information for the given
     * parameters using a Rest client.
     *
     * @param tenantId
     *            - identifier of the tenant.
     * @param electionEventId
     *            - identifier of the election event .
     * @param credentialId
     *            - identifier of the credential .
     * @return an AuthenticationInformation object if found
     * @throws ResourceNotFoundException
     */
    @Override
    public CredentialInformation findByTenantElectionEventCredential(String tenantId, String electionEventId,
                                                                     String credentialId) throws ResourceNotFoundException, ApplicationException {

        LOG.info(I18N.getMessage("CredentialInformationRepoImpl.getAuthInfo"), tenantId, electionEventId,
            credentialId);

        try {
            CredentialInformation credentialInformation = RetrofitConsumer.processResponse(authenticationClient.findByTenantElectionEventCredential(
                trackId.getTrackId(), AUTHENTICATION_INFORMATION_PATH, tenantId, electionEventId, credentialId));
            LOG.info(I18N.getMessage("CredentialInformationRepoImpl.getAuthInfo.found"), tenantId, electionEventId,
                credentialId);

            secureLoggerWriter.log(Level.INFO,
                new LogContent.LogContentBuilder().logEvent(VotingWorkflowLogEvents.CREDENTIAL_DATA_FOUND)
                    .objectId(credentialId).user(credentialId).electionEvent(electionEventId)
                    .additionalInfo(VotingWorkflowLogConstants.INFO_TRACK_ID, trackId.getTrackId())
                    .createLogInfo());

            return credentialInformation;
        } catch (ResourceNotFoundException e) {
            LOG.error(I18N.getMessage("CredentialInformationRepoImpl.getAuthInfo.notFound"), tenantId, electionEventId,
                credentialId);

            secureLoggerWriter.log(Level.ERROR,
                new LogContent.LogContentBuilder().logEvent(VotingWorkflowLogEvents.CREDENTIAL_DATA_NOT_FOUND)
                    .objectId(credentialId).user(credentialId).electionEvent(electionEventId)
                    .additionalInfo(VotingWorkflowLogConstants.INFO_TRACK_ID, trackId.getTrackId())
                    .additionalInfo(VotingWorkflowLogConstants.INFO_ERR_DESC,
                        "Credential data not found: " + ExceptionUtils.getRootCauseMessage(e))
                    .createLogInfo());
            throw e;
        }
    }
}
