/*
 * 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.ei.services.infrastructure.persistence;

import javax.decorator.Decorator;
import javax.decorator.Delegate;
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.DuplicateEntryException;
import com.scytl.products.ov.commons.beans.exceptions.ResourceNotFoundException;
import com.scytl.products.ov.commons.tracking.TrackIdInstance;
import com.scytl.products.ov.ei.services.domain.model.content.ElectoralAuthorityEntity;
import com.scytl.products.ov.ei.services.domain.model.content.ElectoralAuthorityRepository;
import com.scytl.products.ov.ei.services.infrastructure.log.ElectionInformationLogConstants;
import com.scytl.products.ov.ei.services.infrastructure.log.ElectionInformationLogEvents;


/**
 * Electoral Authority repository decorator that adds secure logging
 */
@Decorator
public abstract class ElectoralAuthorityRepositoryDecorator implements ElectoralAuthorityRepository {

    @Inject
    @Delegate
    private ElectoralAuthorityRepository electoralAuthorityRepository;

    @Inject
    private SecureLoggingWriter secureLoggingWriter;

    @Inject
    private TrackIdInstance trackId;

    @Override
    public ElectoralAuthorityEntity find(final Integer electoralAuthorityId) {
        return electoralAuthorityRepository.find(electoralAuthorityId);
    }

    @Override
    public ElectoralAuthorityEntity save(final ElectoralAuthorityEntity entity) throws DuplicateEntryException {
        try {
            final ElectoralAuthorityEntity codesMappingEntity = electoralAuthorityRepository.save(entity);
            secureLoggingWriter.log(Level.INFO,
                new LogContent.LogContentBuilder().logEvent(ElectionInformationLogEvents.ELECTORAL_AUTHORITY_SAVED)
                    .objectId(entity.getElectoralAuthorityId()).user("admin")
                    .electionEvent(entity.getElectionEventId())
                    .additionalInfo(ElectionInformationLogConstants.INFO_TRACK_ID, trackId.getTrackId())
                    .createLogInfo());
            return codesMappingEntity;
        } catch (DuplicateEntryException ex) {
            secureLoggingWriter
                .log(Level.ERROR,
                    new LogContent.LogContentBuilder().logEvent(ElectionInformationLogEvents.ERROR_SAVING_ELECTORAL_AUTHORITY)
                        .objectId(entity.getElectoralAuthorityId()).user("admin")
                        .electionEvent(entity.getElectionEventId())
                        .additionalInfo(ElectionInformationLogConstants.INFO_TRACK_ID, trackId.getTrackId())
                        .additionalInfo(ElectionInformationLogConstants.INFO_ERR_DESC, ex.getMessage())
                        .createLogInfo());
            throw ex;
        }
    }

    @Override
    public ElectoralAuthorityEntity findByTenantIdElectionEventIdElectoralAuthorityId(final String tenantId,
                                                                                      final String electionEventId,
                                                                                      final String electoralAuthorityId)
        throws ResourceNotFoundException {
        try {
            final ElectoralAuthorityEntity electoralAuthorityEntity = electoralAuthorityRepository
                .findByTenantIdElectionEventIdElectoralAuthorityId(tenantId, electionEventId, electoralAuthorityId);
            secureLoggingWriter.log(Level.INFO,
                new LogContent.LogContentBuilder().logEvent(ElectionInformationLogEvents.ELECTORAL_AUTHORITY_FOUND)
                    .objectId(electoralAuthorityId).user("").electionEvent(electionEventId)
                    .additionalInfo(ElectionInformationLogConstants.INFO_TRACK_ID, trackId.getTrackId())
                    .additionalInfo(ElectionInformationLogConstants.INFO_ELECTORAL_AUTHORITY_ID, electoralAuthorityId)
                    .createLogInfo());
            return electoralAuthorityEntity;
        } catch (ResourceNotFoundException ex) {
            secureLoggingWriter.log(Level.ERROR,
                new LogContent.LogContentBuilder().logEvent(ElectionInformationLogEvents.ELECTORAL_AUTHORITY_NOT_FOUND)
                    .objectId(electoralAuthorityId).user("").electionEvent(electionEventId)
                    .additionalInfo(ElectionInformationLogConstants.INFO_TRACK_ID, trackId.getTrackId())
                    .additionalInfo(ElectionInformationLogConstants.INFO_ELECTORAL_AUTHORITY_ID, electoralAuthorityId)
                    .additionalInfo(ElectionInformationLogConstants.INFO_ERR_DESC,
                        ElectionInformationLogEvents.ELECTORAL_AUTHORITY_NOT_FOUND.getInfo())
                    .createLogInfo());
            throw ex;
        }
    }
}
