/*
 * 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.ballot.Ballot;
import com.scytl.products.ov.ei.services.domain.model.ballot.BallotRepository;
import com.scytl.products.ov.ei.services.infrastructure.log.ElectionInformationLogConstants;
import com.scytl.products.ov.ei.services.infrastructure.log.ElectionInformationLogEvents;

/**
 * Decorator for the ballot repository.
 */
@Decorator
public abstract class BallotRepositoryDecorator implements BallotRepository {

    @Inject
    @Delegate
    private BallotRepository ballotRepository;

    @Inject
    private TrackIdInstance trackId;

    @Inject
    private SecureLoggingWriter secureLoggerWriter;

    /**
     * @see com.scytl.products.ov.ei.services.domain.model.ballot.BallotRepository#findByTenantIdElectionEventIdBallotId(java.lang.String,
     *      java.lang.String, java.lang.String)
     */
    @Override
    public Ballot findByTenantIdElectionEventIdBallotId(String tenantId, String electionEventId, String ballotId)
        throws ResourceNotFoundException {
        try {
            Ballot result = ballotRepository.findByTenantIdElectionEventIdBallotId(tenantId, electionEventId, ballotId);
            secureLoggerWriter.log(Level.INFO,
                new LogContent.LogContentBuilder().logEvent(ElectionInformationLogEvents.BALLOT_FOUND).objectId(ballotId)
                    .user("").electionEvent(electionEventId)
                    .additionalInfo(ElectionInformationLogConstants.INFO_TRACK_ID, trackId.getTrackId())
                    .additionalInfo(ElectionInformationLogConstants.INFO_BALLOT_ID, ballotId).createLogInfo());

            return result;
        } catch (ResourceNotFoundException e) {
            secureLoggerWriter.log(Level.ERROR, new LogContent.LogContentBuilder()
                .logEvent(ElectionInformationLogEvents.BALLOT_NOT_FOUND).objectId(ballotId).user("")
                .electionEvent(electionEventId)
                .additionalInfo(ElectionInformationLogConstants.INFO_TRACK_ID, trackId.getTrackId())
                .additionalInfo(ElectionInformationLogConstants.INFO_BALLOT_ID, ballotId)
                .additionalInfo(ElectionInformationLogConstants.INFO_ERR_DESC, "Resource not found in the BALLOT table.")
                .createLogInfo());
            throw e;
        }
    }

    @Override
    public Ballot save(final Ballot ballot) throws DuplicateEntryException {
        try {
            Ballot savedBallot = ballotRepository.save(ballot);
            secureLoggerWriter.log(Level.INFO,
                new LogContent.LogContentBuilder().logEvent(ElectionInformationLogEvents.BALLOT_SAVED)
                    .objectId(ballot.getBallotId()).user("").electionEvent(ballot.getElectionEventId())
                    .additionalInfo(ElectionInformationLogConstants.INFO_TRACK_ID, trackId.getTrackId())
                    .additionalInfo(ElectionInformationLogConstants.INFO_BALLOT_ID, ballot.getBallotId())
                    .createLogInfo());

            return savedBallot;
        } catch (DuplicateEntryException ex) {
            secureLoggerWriter.log(Level.INFO,
                new LogContent.LogContentBuilder().logEvent(ElectionInformationLogEvents.ERROR_SAVING_BALLOT)
                    .objectId(ballot.getBallotId()).user("").electionEvent(ballot.getElectionEventId())
                    .additionalInfo(ElectionInformationLogConstants.INFO_TRACK_ID, trackId.getTrackId())
                    .additionalInfo(ElectionInformationLogConstants.INFO_BALLOT_ID, ballot.getBallotId())
                    .additionalInfo(ElectionInformationLogConstants.INFO_ERR_DESC, ex.getMessage())
                    .createLogInfo());
            throw ex;
        }
    }
}
