/*
 * 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.challenge;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.when;

import java.util.Arrays;
import java.util.Iterator;

import javax.enterprise.inject.Instance;

import com.scytl.products.ov.commons.validation.ValidationResult;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import org.slf4j.Logger;

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.au.services.domain.model.challenge.ChallengeInformation;
import com.scytl.products.ov.au.services.domain.model.validation.ChallengeInformationValidation;
import com.scytl.products.ov.commons.beans.exceptions.ResourceNotFoundException;
import com.scytl.products.ov.commons.beans.validation.CryptographicOperationException;
import com.scytl.products.ov.commons.tracking.TrackIdInstance;

@RunWith(MockitoJUnitRunner.class)
public class ChallengeInformationValidationServiceTest {

	@InjectMocks
	ChallengeInformationValidationService validationService = new ChallengeInformationValidationService();

	@Mock
	ChallengeInformation challengeInformationMock = new ChallengeInformation();

	@Mock
	Instance<ChallengeInformationValidation> challengeInformationValidationsMock;

	@Mock
	Iterator<ChallengeInformationValidation> iteratorMock1;

	@Mock
	Iterator<ChallengeInformationValidation> iteratorMock2;

	@Mock
	ChallengeInformationValidation challengeInformationValidationMock;

	@Mock
	Logger logger;

	@Mock
	private SecureLoggingWriter secureLoggerWriter;

	@Mock
	private TrackIdInstance trackId;


	ChallengeInformationCredentialIdValidation rule1 = new ChallengeInformationCredentialIdValidation();
	ChallengeInformationExpirationTimeValidation rule2 = new ChallengeInformationExpirationTimeValidation();
	ChallengeClientInformationSignatureValidation rule3 = new ChallengeClientInformationSignatureValidation();
	ChallengeServerInformationSignatureValidation rule4 = new ChallengeServerInformationSignatureValidation();




	@Before
	public void setup() {
		doNothing().when(secureLoggerWriter).log(any(Level.class), any(LogContent.class));
	}

	@Test
	public void testCreation(){

		when(challengeInformationValidationsMock.iterator()).thenReturn(Arrays.asList(rule1, rule2, rule3, rule4).iterator());
		validationService.setValidations(challengeInformationValidationsMock);

	}

	@Test
	public void validateFalse() throws ResourceNotFoundException, CryptographicOperationException {
		when(challengeInformationValidationsMock.iterator()).thenReturn(iteratorMock1);
		when(iteratorMock1.hasNext()).thenReturn(true, false);
		when(iteratorMock1.next()).thenReturn(challengeInformationValidationMock);
		validationService.setValidations(challengeInformationValidationsMock);

		String tenantId = "1";
		String electionEventId = "1";
		String votingCardId = "1";
		when(challengeInformationValidationMock.execute(tenantId, electionEventId, votingCardId, challengeInformationMock))
			.thenReturn(false);

		ValidationResult result =
			validationService.validate(tenantId, electionEventId, votingCardId, challengeInformationMock);

		assertFalse(result.isResult());
	}

	@Test
	public void validateTrue() throws ResourceNotFoundException, CryptographicOperationException {
		when(challengeInformationValidationsMock.iterator()).thenReturn(iteratorMock2);
		when(iteratorMock2.hasNext()).thenReturn(true, false);
		when(iteratorMock2.next()).thenReturn(challengeInformationValidationMock);
		validationService.setValidations(challengeInformationValidationsMock);

		String tenantId = "1";
		String electionEventId = "1";
		String votingCardId = "1";
		when(challengeInformationValidationMock.execute(tenantId, electionEventId, votingCardId, challengeInformationMock))
			.thenReturn(true);
		
		ValidationResult result =
			validationService.validate(tenantId, electionEventId, votingCardId, challengeInformationMock);

		assertTrue(result.isResult());
	}
}
