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

import static org.junit.Assert.*;

import java.io.IOException;
import java.io.OutputStream;
import java.security.Security;

import static org.mockito.Mockito.when;
import static org.mockito.Mockito.doThrow;

import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.mockito.runners.MockitoJUnitRunner;
import org.slf4j.Logger;

import com.scytl.products.oscore.logging.api.writer.SecureLoggingWriter;
import com.scytl.products.ov.commons.beans.exceptions.ApplicationException;
import com.scytl.products.ov.commons.beans.exceptions.DuplicateEntryException;
import com.scytl.products.ov.commons.beans.exceptions.EntryPersistenceException;
import com.scytl.products.ov.commons.beans.exceptions.ResourceNotFoundException;
import com.scytl.products.ov.commons.tracking.TrackIdInstance;
import com.scytl.products.ov.vw.infrastructure.log.SecureLoggerInformation;
import com.scytl.products.ov.vw.services.domain.model.state.VotingCardState;
import com.scytl.products.ov.vw.services.domain.model.state.VotingCardStates;

@RunWith(MockitoJUnitRunner.class)
public class VotingCardStateServiceDecoratorTest {
	
	@Mock
	VotingCardStateService votingCardStateService;
	
	@Mock
	private TrackIdInstance trackIdInstance;

	@Mock
	private SecureLoggingWriter secureLoggerWriter;		
	
	@Mock
	private SecureLoggerInformation secureLoggerInformation;
	
	@Mock
	private Logger logger;
	
	@InjectMocks
	private VotingCardStateServiceDecorator sut = new VotingCardStateServiceDecorator() {
		
		// Need to implement empty unused functions
		@Override
		public void writeIdAndStateOfInactiveVotingCards(String tenantId, String electionEventId, OutputStream stream)	throws IOException {}

		@Override
		public void incrementVotingCardAttempts(String tenantId, String electionEventId, String votingCardId)	throws ResourceNotFoundException, ApplicationException, DuplicateEntryException {}
		
		@Override
		public void initializeVotingCardState(VotingCardState votingCardState)
				throws DuplicateEntryException, EntryPersistenceException, ResourceNotFoundException {}
		
		@Override
		public void blockVotingCardIgnoreUnable(String tenantId, String electionEventId, String votingCardId)
				throws ResourceNotFoundException, ApplicationException, DuplicateEntryException {}
	};
			
	@BeforeClass
	public static void setup() 	{
		MockitoAnnotations.initMocks(VotingCardStateServiceDecoratorTest.class);
	    Security.addProvider(new BouncyCastleProvider());
	}

	@Test
	public void testGetVotingCardStateSuccessful() throws ResourceNotFoundException, ApplicationException, DuplicateEntryException {
		String tenantId = "1";
		String electionEventId = "1";
		String votingCardId = "1";
		
		VotingCardState votingCardStateMock = new VotingCardState();
		votingCardStateMock.setState(VotingCardStates.SENT_BUT_NOT_CAST);
		
		when(votingCardStateService.getVotingCardState(tenantId, electionEventId, votingCardId)).thenReturn(votingCardStateMock);
		VotingCardState votingCardStateResult = sut.getVotingCardState(tenantId, electionEventId, votingCardId);
		
		assertEquals(votingCardStateMock, votingCardStateResult);
	}
	
    @Test(expected=ApplicationException.class)
	public void testGetVotingCardStateApplicationException() throws ResourceNotFoundException, ApplicationException, DuplicateEntryException {
		String tenantId = "1";
		String electionEventId = "1";
		String votingCardId = "1";
		
		VotingCardState votingCardStateMock = new VotingCardState();
		votingCardStateMock.setState(VotingCardStates.SENT_BUT_NOT_CAST);
		
		when(votingCardStateService.getVotingCardState(tenantId, electionEventId, votingCardId)).thenThrow(new ApplicationException("exception"));
		sut.getVotingCardState(tenantId, electionEventId, votingCardId);
	}
	
	@Test
	public void updateVotingCardStateSuccessful() throws ResourceNotFoundException, ApplicationException, DuplicateEntryException {
		String tenantId = "1";
		String electionEventId = "1";
		String votingCardId = "1";
		
		sut.updateVotingCardState(tenantId, electionEventId, votingCardId, VotingCardStates.NOT_SENT);
	}
	
	@Test(expected=ResourceNotFoundException.class)
	public void updateVotingCardStateResourceNotFoundException() throws ResourceNotFoundException, ApplicationException, DuplicateEntryException {
		String tenantId = "1";
		String electionEventId = "1";
		String votingCardId = "1";
		
		doThrow(ResourceNotFoundException.class).when(votingCardStateService).updateVotingCardState(tenantId, electionEventId, votingCardId, VotingCardStates.NOT_SENT);
		sut.updateVotingCardState(tenantId, electionEventId, votingCardId, VotingCardStates.NOT_SENT);
	}

}
