/*
 * 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.vv.domain.service;

import javax.decorator.Decorator;
import javax.decorator.Delegate;
import javax.inject.Inject;

import org.apache.commons.lang3.exception.ExceptionUtils;

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.domain.model.vote.Vote;
import com.scytl.products.ov.commons.beans.exceptions.ApplicationException;
import com.scytl.products.ov.commons.tracking.TrackIdInstance;
import com.scytl.products.ov.commons.validation.ValidationResult;
import com.scytl.products.ov.vv.infrastructure.log.SecureLoggerHelper;
import com.scytl.products.ov.vv.infrastructure.log.VoteVerificationLogConstants;
import com.scytl.products.ov.vv.infrastructure.log.VoteVerificationLogEvents;

/**
 * Decorator of the ballot box information repository.
 */
@Decorator
public abstract class ValidationServiceDecorator implements ValidationService {

    @Inject
    @Delegate
    private ValidationService validationService;

    @Inject
    private TrackIdInstance trackId;

    @Inject
    private SecureLoggingWriter secureLoggerWriter;

    @Inject
    private SecureLoggerHelper secureLoggerHelper;

    /**
     * @see com.scytl.products.ov.vv.domain.service.ValidationService#validate(com.scytl.products.ov.commons.beans.domain.model.vote.Vote)
     */
    @Override
    public ValidationResult validate(Vote vote) throws ApplicationException {
        try {
            ValidationResult result = validationService.validate(vote);
            if (result.isResult()) {
                secureLoggerWriter.log(Level.INFO,
                    new LogContent.LogContentBuilder().logEvent(VoteVerificationLogEvents.VALID_VOTE)
                        .objectId(vote.getVerificationCardId()).user(vote.getVerificationCardId())
                        .electionEvent(vote.getElectionEventId())
                        .additionalInfo(VoteVerificationLogConstants.INFO_TRACK_ID, trackId.getTrackId())
                        .additionalInfo(VoteVerificationLogConstants.INFO_HASH_VOTE, secureLoggerHelper.hash(vote))
                        .createLogInfo());
            } else {
                secureLoggerWriter.log(Level.ERROR,
                    new LogContent.LogContentBuilder().logEvent(VoteVerificationLogEvents.ERROR_VOTE_VALIDATION)
                        .objectId(vote.getVerificationCardId()).user(vote.getVerificationCardId())
                        .electionEvent(vote.getElectionEventId())
                        .additionalInfo(VoteVerificationLogConstants.INFO_TRACK_ID, trackId.getTrackId())
                        .additionalInfo(VoteVerificationLogConstants.INFO_HASH_VOTE, secureLoggerHelper.hash(vote))
                        .additionalInfo(VoteVerificationLogConstants.INFO_VERIFICATION_CARD_ID,
                            vote.getVerificationCardId())
                        .additionalInfo(VoteVerificationLogConstants.INFO_ERR_DESC,
                            "Validations over the vote structure fails")
                        .createLogInfo());
            }
            return result;
        } catch (ApplicationException e) {
            secureLoggerWriter.log(Level.ERROR,
                new LogContent.LogContentBuilder().logEvent(VoteVerificationLogEvents.ERROR_VOTE_VALIDATION)
                    .objectId(vote.getVerificationCardId()).user(vote.getVerificationCardId())
                    .electionEvent(vote.getElectionEventId())
                    .additionalInfo(VoteVerificationLogConstants.INFO_TRACK_ID, trackId.getTrackId())
                    .additionalInfo(VoteVerificationLogConstants.INFO_HASH_VOTE, secureLoggerHelper.hash(vote))
                    .additionalInfo(VoteVerificationLogConstants.INFO_VERIFICATION_CARD_ID,
                        vote.getVerificationCardId())
                    .additionalInfo(VoteVerificationLogConstants.INFO_ERR_DESC,
                        "Error validating the vote: " + ExceptionUtils.getRootCauseMessage(e))
                    .createLogInfo());
            throw e;
        }
    }
}
