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

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

import static org.mockito.Mockito.when;
import static org.junit.Assert.assertEquals;

import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
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.ResourceNotFoundException;
import com.scytl.products.ov.commons.infrastructure.remote.client.RetrofitException;
import com.scytl.products.ov.commons.tracking.TrackIdInstance;
import com.scytl.products.ov.vw.services.domain.model.authentication.CredentialInformation;

import retrofit2.Call;
import retrofit2.Response;
import okhttp3.ResponseBody;


@RunWith(MockitoJUnitRunner.class)
public class CredentialInformationRepositoryImplTest {
	
	private final String TENANT_ID = "100";
	private final String ELECTION_EVENT_ID = "1";
	private final String CREDENTIAL_ID = "1";
	private final String TRACK_ID = "1";
	
	// this value has to correspond with Application.properties:AUTHENTICATION_INFORMATION_PATH
	private final String AUTHENTICATION_INFORMATION_PATH_VALUE = "informations";

    @Mock
    private Logger LOG;

    @Mock
    private TrackIdInstance trackId;

    @Mock
    private SecureLoggingWriter secureLoggerWriter;
    
    @Mock
    private AuthenticationClient authenticationClient;
    
    @InjectMocks
    CredentialInformationRepositoryImpl rut = new CredentialInformationRepositoryImpl(authenticationClient);
    
	@BeforeClass
	public static void setup() 	{
	    Security.addProvider(new BouncyCastleProvider());
	}
	
	@Before
	public void init()
	{
		when(trackId.getTrackId()).thenReturn(TRACK_ID);
	}
    
    @Test
    public void testFindCredentialInfoSuccessful() throws ResourceNotFoundException, ApplicationException, IOException
    {
    	CredentialInformation credentialInformationMock = new CredentialInformation();
    	credentialInformationMock.setCertificates("1");

        @SuppressWarnings("unchecked")
		Call<CredentialInformation> callMock = (Call<CredentialInformation>) Mockito.mock(Call.class);
    	when(callMock.execute()).thenReturn(Response.success(credentialInformationMock));

    	when(authenticationClient.findByTenantElectionEventCredential(TRACK_ID, AUTHENTICATION_INFORMATION_PATH_VALUE, TENANT_ID, ELECTION_EVENT_ID, ELECTION_EVENT_ID)).thenReturn(callMock);
    	
    	CredentialInformation credentialInformation = rut.findByTenantElectionEventCredential(TENANT_ID, ELECTION_EVENT_ID, CREDENTIAL_ID);
    	assertEquals(credentialInformationMock, credentialInformation);
    }
    
    @Test(expected=ResourceNotFoundException.class)
    public void testFindCredentialInfoResourceNotFoundException() throws ResourceNotFoundException, ApplicationException, IOException
    {

    	when(authenticationClient.findByTenantElectionEventCredential(TRACK_ID, AUTHENTICATION_INFORMATION_PATH_VALUE, TENANT_ID, ELECTION_EVENT_ID, ELECTION_EVENT_ID)).thenThrow(new ResourceNotFoundException("exception"));
    	
    	rut.findByTenantElectionEventCredential(TENANT_ID, ELECTION_EVENT_ID, CREDENTIAL_ID);
    }
    
    @Test(expected=ResourceNotFoundException.class)
    public void testFindCredentialInfo404Error() throws ResourceNotFoundException, ApplicationException, IOException
    {
        @SuppressWarnings("unchecked")
		Call<CredentialInformation> callMock = (Call<CredentialInformation>) Mockito.mock(Call.class);
    	when(callMock.execute()).thenReturn(Response.error(404,  ResponseBody.create(okhttp3.MediaType.parse("text/html"), new byte[0])));

    	when(authenticationClient.findByTenantElectionEventCredential(TRACK_ID, AUTHENTICATION_INFORMATION_PATH_VALUE, TENANT_ID, ELECTION_EVENT_ID, ELECTION_EVENT_ID)).thenReturn(callMock);
    	
    	rut.findByTenantElectionEventCredential(TENANT_ID, ELECTION_EVENT_ID, CREDENTIAL_ID);
    }
    
    @Test(expected=RetrofitException.class)
    public void testFindCredentialInfo500Error() throws ResourceNotFoundException, ApplicationException, IOException
    {
        @SuppressWarnings("unchecked")
		Call<CredentialInformation> callMock = (Call<CredentialInformation>) Mockito.mock(Call.class);
    	when(callMock.execute()).thenReturn(Response.error(500,  ResponseBody.create(okhttp3.MediaType.parse("text/html"), new byte[0])));

    	when(authenticationClient.findByTenantElectionEventCredential(TRACK_ID, AUTHENTICATION_INFORMATION_PATH_VALUE, TENANT_ID, ELECTION_EVENT_ID, ELECTION_EVENT_ID)).thenReturn(callMock);
    	
    	rut.findByTenantElectionEventCredential(TENANT_ID, ELECTION_EVENT_ID, CREDENTIAL_ID);
    }

}

