/*
 * 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 com.google.common.cache.Cache;
import org.slf4j.Logger;

import javax.ejb.Stateless;
import javax.inject.Inject;
import java.util.StringJoiner;
import java.util.concurrent.ExecutionException;

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.services.domain.model.information.ElectionEventTranslation;
import com.scytl.products.ov.vw.services.domain.model.information.KeyTranslationRepository;

/**
 * Implementation of the repository.
 */
@Stateless
public class KeyTranslationRepositoryImpl implements KeyTranslationRepository {

	// PropertiesFile
	private static final PropertiesFileReader PROPERTIES = PropertiesFileReader.getInstance();

	// The path to the resource validations.
	private static final String KEY_TRANSLATION_PATH = PROPERTIES.getPropertyValue("KEY_TRANSLATION_PATH");

	// Instance of the track Id which will be written in the logs
	@Inject
	private TrackIdInstance trackId;

	private KeyTranslationClient keyTranslationClient;

    // Instance of the secure logger
    @Inject
    private Logger LOG;

    @Inject
    private Cache<String, Object> cache;

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

	@Inject
    KeyTranslationRepositoryImpl(final KeyTranslationClient keyTranslationClient) {
        this.keyTranslationClient = keyTranslationClient;
    }

	@Override
	public ElectionEventTranslation getByElectionEventId(final String tenantId, final String electionEventId)
        throws ResourceNotFoundException {

		LOG.info(I18N.getMessage("KeyTranslationRepositoryImpl.getElectionEventTranslation"), tenantId, electionEventId);

        try {
            //if the value is not in the cache, get it form the remote service and put it in the cache (put is automatic)
            return (ElectionEventTranslation) cache.get(createCompositeKey(tenantId, electionEventId),
                () -> this.getFromRemoteService(tenantId, electionEventId));
        }  catch (ExecutionException e) {
            LOG.error("Failed to get data from remote service.", e);
            throw new ResourceNotFoundException(e.getMessage());
        }
    }

    private ElectionEventTranslation getFromRemoteService(final String tenantId, final String electionEventId)
        throws ResourceNotFoundException {
        try {
            ElectionEventTranslation translation = RetrofitConsumer.processResponse(keyTranslationClient.getByElectionEventId(trackId.getTrackId(),
                KEY_TRANSLATION_PATH, tenantId, electionEventId));

            LOG.info(I18N.getMessage("KeyTranslationRepositoryImpl.getElectionEventTranslation.found"),
                tenantId, electionEventId);

            return translation;
        } catch (ResourceNotFoundException e) {
            LOG.error(I18N.getMessage("KeyTranslationRepositoryImpl.getElectionEventTranslation.notFound"),
                tenantId, electionEventId);
            throw e;
        }

    }
    private String createCompositeKey(final String...components) {
        final StringJoiner sj = new StringJoiner("$");
        for(String component : components) {
            sj.add(component);
        }
        return sj.toString();
    }
}
