/*
 * 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.domain.model.rule;

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.validation.ValidationErrorType;
import com.scytl.products.ov.commons.domain.model.rule.AbstractRule;
import com.scytl.products.ov.commons.tracking.TrackIdInstance;
import com.scytl.products.ov.commons.util.JsonUtils;
import com.scytl.products.ov.commons.validation.ValidationError;
import com.scytl.products.ov.ei.services.infrastructure.log.ElectionInformationLogConstants;
import com.scytl.products.ov.ei.services.infrastructure.log.ElectionInformationLogEvents;
import com.scytl.products.ov.ei.services.infrastructure.log.SecureLoggerHelper;

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

/**
 * @author jbarrio
 * @date 23/12/16
 *
 * Copyright (C) 2016 Scytl Secure Electronic Voting SA
 *
 * All rights reserved.
 */
@Decorator
public class BlockedBallotBoxRuleDecorator implements AbstractRule<Vote> {

	// The name of the json parameter timeStamp.
	private static final String JSON_PARAMETER_TIMESTAMP = "timestamp";

	@Inject
	@Delegate
	private BlockedBallotBoxRule blockedBallotBoxRule;

	@Inject
	private SecureLoggingWriter secureLoggerWriter;

	@Inject
	private TrackIdInstance trackId;

	@Inject
	private SecureLoggerHelper secureLoggerHelper;

	/**
	 * This method validates that the ballot box is not blocked before storing the vote.
	 *
	 * @param vote
	 *            - The vote to be validated.
	 * @return True if the vote satisfies the rule. Otherwise, false.
	 */
	@Override
	public ValidationError execute(Vote vote) {
		ValidationError result = blockedBallotBoxRule.execute(vote);
		if (!result.getValidationErrorType().equals(ValidationErrorType.SUCCESS)) {
			secureLog(vote, result.getValidationErrorType());
		}
		return result;
	}

	private void secureLog(Vote vote, ValidationErrorType validationErrorType) {
		String authTokenHash = secureLoggerHelper.getAuthTokenHash(vote.getAuthenticationToken());
		String voteHash = secureLoggerHelper.getVoteHash(vote);
		JsonObject tokenJson = JsonUtils.getJsonObject(vote.getAuthenticationToken());
		String timeStampToken = tokenJson.getString(JSON_PARAMETER_TIMESTAMP);
		String errorMessage = "";
		if (validationErrorType.equals(ValidationErrorType.BLOCKED_BALLOT_BOX)) {
			errorMessage += "This ballot box is blocked.";
		}
		secureLoggerWriter.log(
			Level.WARN,
			new LogContent.LogContentBuilder()
				.logEvent(ElectionInformationLogEvents.BALLOT_BOX_BLOCKED)
				.objectId(authTokenHash)
				.user(vote.getVotingCardId())
				.electionEvent(vote.getElectionEventId())
				.additionalInfo(ElectionInformationLogConstants.INFO_TRACK_ID, trackId.getTrackId())
				.additionalInfo(ElectionInformationLogConstants.INFO_HASH_VOTE, voteHash)
				.additionalInfo(ElectionInformationLogConstants.INFO_TIMESTAMP_AT, timeStampToken)
				.additionalInfo(ElectionInformationLogConstants.INFO_BALLOT_ID, vote.getBallotId())
				.additionalInfo(ElectionInformationLogConstants.INFO_BALLOT_BOX_ID, vote.getBallotBoxId())
				.additionalInfo(ElectionInformationLogConstants.INFO_ERR_DESC, errorMessage)
				.createLogInfo()
		);
	}

	/**
	 * @see com.scytl.products.ov.commons.domain.model.rule.AbstractRule#getName()
	 */
	@Override
	public String getName() {
		return blockedBallotBoxRule.getName();
	}

}
