/*
 * 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.au.services.domain.service.validation;

import java.security.cert.CertificateException;
import java.util.ArrayList;
import java.util.Collection;

import javax.ejb.Stateless;
import javax.enterprise.inject.Any;
import javax.enterprise.inject.Instance;
import javax.inject.Inject;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.scytl.products.ov.commons.beans.domain.model.authentication.AuthenticationContent;
import com.scytl.products.ov.au.services.domain.model.authentication.AuthenticationToken;
import com.scytl.products.ov.commons.beans.exceptions.AuthTokenValidationException;
import com.scytl.products.ov.au.services.domain.model.validation.AuthenticationTokenValidation;
import com.scytl.products.ov.au.services.domain.service.authenticationcontent.AuthenticationContentService;
import com.scytl.products.ov.commons.beans.exceptions.ResourceNotFoundException;
import com.scytl.products.ov.commons.logging.service.I18nLoggerMessages;
import com.scytl.products.ov.commons.validation.ValidationError;
import com.scytl.products.ov.commons.validation.ValidationResult;

/**
 * This service provides the functionality to validate a authentication token based on the predefined rules.
 */
@Stateless
public class AuthenticationTokenValidationServiceImpl implements AuthenticationTokenValidationService {

    private final Collection<AuthenticationTokenValidation> validations = new ArrayList<>();
    
    private static final Logger LOG = LoggerFactory.getLogger("std");
    
    private static final I18nLoggerMessages I18N = I18nLoggerMessages.getInstance();
    
    @Inject
	private AuthenticationContentService authenticationContentService;
	
	@Inject
    @Any
	void setValidations(Instance<AuthenticationTokenValidation> instance) {
	    for (AuthenticationTokenValidation validation : instance) {
            validations.add(validation);
        }
	}

	/**
	 * @see com.scytl.products.ov.au.services.domain.service.validation.AuthenticationTokenValidationService#validate(java.lang.String,
	 *      java.lang.String, java.lang.String,
	 *      com.scytl.products.ov.au.services.domain.model.authentication.AuthenticationToken)
	 */
	@Override
	public ValidationResult validate(String tenantId, String electionEventId, String votingCardId,
									 AuthenticationToken authenticationToken) throws ResourceNotFoundException, CertificateException {
		// result of validation
		ValidationResult validationResult = new ValidationResult(true);

		try {
			// execute validations
			for (AuthenticationTokenValidation validation : validations) {
				validation.execute(tenantId, electionEventId, votingCardId, authenticationToken);
			}
		}catch (AuthTokenValidationException atE){
			LOG.info(I18N.getMessage("AuthenticationTokenValidationService.validate.validationError"), atE);
			validationResult.setResult(false);
			validationResult.setValidationError(new ValidationError(atE.getErrorType()));
		}

		return validationResult;
	}

	/**
	 * @see com.scytl.products.ov.au.services.domain.service.validation.AuthenticationTokenValidationService#getAuthenticationContent(java.lang.String,
	 *      java.lang.String)
	 */
	@Override
	public AuthenticationContent getAuthenticationContent(String tenantId, String electionEventId)
			throws ResourceNotFoundException {
		return authenticationContentService.getAuthenticationContent(tenantId, electionEventId);
	}
}
