/*
 * 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.sdm.application.service;

import javax.json.JsonObject;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.fasterxml.jackson.databind.ObjectMapper;
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.ResourceNotFoundException;
import com.scytl.products.ov.commons.path.PathResolver;
import com.scytl.products.ov.sdm.application.log.SdmSecureLogEvent;
import com.scytl.products.ov.sdm.domain.model.status.InvalidStatusTransitionException;
import com.scytl.products.ov.sdm.domain.model.status.Status;
import com.scytl.products.ov.sdm.domain.model.votingcardset.VotingCardSetRepository;
import com.scytl.products.ov.sdm.infrastructure.JsonConstants;

/**
 * This is an application service that manages voting card sets.
 */
@Service
class BaseVotingCardSetService {

    @Autowired
    protected PathResolver pathResolver;

    @Autowired
    protected VotingCardSetRepository votingCardSetRepository;

    @Autowired
    protected ObjectMapper objectMapper;

    @Autowired
    private SecureLoggingWriter secureLogger;

    /**
     * Check whether a voting card set can be transitioned from this status.
     *
     * @param electionEventId
     *            the election event the voting card set is for.
     * @param votingCardSetId
     *            the voting card set to check.
     * @param from
     *            the expected current status
     * @param to
     *            the expected final status
     * @throws InvalidStatusTransitionException
     * @throws ResourceNotFoundException
     */
	protected void checkVotingCardSetStatusTransition(String electionEventId, String votingCardSetId, Status from,
			Status to) throws ResourceNotFoundException, InvalidStatusTransitionException {
		JsonObject votingCardSetJson = votingCardSetRepository.getVotingCardSetJson(electionEventId, votingCardSetId);
		
		if (votingCardSetJson != null) {
			if (!(votingCardSetJson.containsKey(JsonConstants.JSON_ATTRIBUTE_NAME_STATUS)
					&& votingCardSetJson.getString(JsonConstants.JSON_ATTRIBUTE_NAME_STATUS).equals(from.name()))) {
				throw new InvalidStatusTransitionException(
						Status.valueOf(votingCardSetJson.getString(JsonConstants.JSON_ATTRIBUTE_NAME_STATUS)), to);
			}
		} else {
			throw new InvalidStatusTransitionException(null, to);
		}
	}

    /**
     * Sends an event to the secure log.
     *
     * @param event
     *            the event to be logged
     * @param electionEventId
     *            the election event ID
     * @param votingCardSetId
     *            the voting card set ID
     */
    protected void secureLog(SdmSecureLogEvent event, String electionEventId, String votingCardSetId) {
        secureLogger.log(Level.INFO, new LogContent.LogContentBuilder().logEvent(event).objectId(votingCardSetId)
            .electionEvent(electionEventId).createLogInfo());
    }


    protected void validateIds(String votingCardSetId, String electionEventId) throws IllegalArgumentException {
        if (StringUtils.isEmpty(votingCardSetId) || StringUtils.isEmpty(electionEventId)) {
            secureLogger.log(Level.ERROR,
                new LogContent.LogContentBuilder().logEvent(SdmSecureLogEvent.VCS_PRECOMPUTATION_FAILED)
                    .objectId(votingCardSetId).electionEvent(electionEventId)
                    .additionalInfo("#err_desc", "electionEventId or votingCardSetId is empty").createLogInfo());
            throw new IllegalArgumentException("electionEventId or votingCardSetId is empty");
        }
    }
}
