/*
 * 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.vv.ui.ws.rs.application.operation;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.core.Is.is;

import javax.transaction.HeuristicMixedException;
import javax.transaction.HeuristicRollbackException;
import javax.transaction.NotSupportedException;
import javax.transaction.RollbackException;
import javax.transaction.SystemException;
import javax.ws.rs.client.Entity;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;

import org.jboss.arquillian.extension.rest.client.ArquillianResteasyResource;
import org.jboss.arquillian.junit.Arquillian;
import org.jboss.resteasy.client.jaxrs.ResteasyWebTarget;
import org.junit.Test;
import org.junit.runner.RunWith;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.scytl.products.ov.commons.beans.ElectoralAuthority;
import com.scytl.products.ov.commons.configuration.JSONSignatureConfiguration;
import com.scytl.products.ov.commons.sign.JSONSigner;
import com.scytl.products.ov.vv.domain.model.content.ElectoralAuthorityEntity;

@RunWith(Arquillian.class)
public class ElectoralDataResourceTest extends VoteVerificationArquillianTest {
	
	private final String ADMIN_BOARD_ID = "5b4517223d0a40aa94badf6f1ad32152";
	private final String ELECTORAL_AUTHORITY_ID = "123456789";
	
	private final String ELECTORAL_AUTHORITY_JSON = "first-ea-authority-saved";

	// Paths
	private final String SAVE_ELECTORAL_DATA_PATH = ElectoralDataResource.RESOURCE_PATH + ElectoralDataResource.SAVE_ELECTORAL_DATA_PATH;

	@Test
	public void testSaveElectoralData_Successful(@ArquillianResteasyResource("") final ResteasyWebTarget webTarget) 
			throws JsonProcessingException, SecurityException, IllegalStateException, RollbackException, HeuristicMixedException, HeuristicRollbackException, SystemException, NotSupportedException
	{
		String url = addPathValues(SAVE_ELECTORAL_DATA_PATH,
										ElectoralDataResource.QUERY_PARAMETER_TENANT_ID, TENANT_ID,
										ElectoralDataResource.QUERY_PARAMETER_ELECTION_EVENT_ID, ELECTION_EVENT_ID,
										ElectoralDataResource.QUERY_PARAMETER_ELECTORAL_AUTHORITY_ID, ELECTORAL_AUTHORITY_ID,
										ElectoralDataResource.QUERY_PARAMETER_ADMIN_BOARD_ID, ADMIN_BOARD_ID);
		
		String entity = "{\"electoralAuthority\": { \"signature\":\""+getElectoralAuthoritySignature()+"\" } }";
		
		Response response = webTarget.path(url).request(MediaType.APPLICATION_JSON_TYPE).post(Entity.entity(entity, MediaType.APPLICATION_JSON_TYPE));
		
		assertThat(response.getStatus(), is(STATUS_OK));
		
		ElectoralAuthorityEntity savedElectoralAuthority = getSavedObject(ElectoralAuthorityEntity.class, "electoralAuthorityId", ELECTORAL_AUTHORITY_ID);
		assertThat(savedElectoralAuthority.getElectionEventId(), is(ELECTION_EVENT_ID));
	}

	private String getElectoralAuthoritySignature() {
		ElectoralAuthority electoralAuthority = new ElectoralAuthority();
		electoralAuthority.setId("electoralAuthorityId");
		electoralAuthority.setPublicKey("electoralAuthorityPublicKey");
		String electoralAuthorityJsonSigned = new JSONSigner(JSONSignatureConfiguration.RSA_PSS_SHA256).sign(VoteVerificationArquillianDeployment.keyPair.getPrivate(), electoralAuthority);
		
		return electoralAuthorityJsonSigned;
	}
	
	@Test
	public void testSaveElectoralData_Duplicate(@ArquillianResteasyResource("") final ResteasyWebTarget webTarget) throws SecurityException, IllegalStateException, NotSupportedException, SystemException, RollbackException, HeuristicMixedException, HeuristicRollbackException  
	{
		createDuplicateElectoralAuthorityEntity();
		
		String url = addPathValues(SAVE_ELECTORAL_DATA_PATH,
				ElectoralDataResource.QUERY_PARAMETER_TENANT_ID, TENANT_ID,
				ElectoralDataResource.QUERY_PARAMETER_ELECTION_EVENT_ID, ELECTION_EVENT_ID,
				ElectoralDataResource.QUERY_PARAMETER_ELECTORAL_AUTHORITY_ID, ELECTORAL_AUTHORITY_ID,
				ElectoralDataResource.QUERY_PARAMETER_ADMIN_BOARD_ID, ADMIN_BOARD_ID);

		String entity = "{\"electoralAuthority\": { \"signature\":\""+getElectoralAuthoritySignature()+"\" } }";
		
		Response response = webTarget.path(url).request(MediaType.APPLICATION_JSON_TYPE).post(Entity.entity(entity, MediaType.APPLICATION_JSON_TYPE));
		
		assertThat(response.getStatus(), is(STATUS_OK));
		
		ElectoralAuthorityEntity savedElectoralAuthority = getSavedObject(ElectoralAuthorityEntity.class, "electoralAuthorityId", ELECTORAL_AUTHORITY_ID);
		assertThat(savedElectoralAuthority.getElectionEventId(), is(ELECTION_EVENT_ID));
		assertThat(savedElectoralAuthority.getJson(), is(ELECTORAL_AUTHORITY_JSON));
	}
	
	private void createDuplicateElectoralAuthorityEntity() throws NotSupportedException, SystemException, SecurityException, IllegalStateException, RollbackException, HeuristicMixedException, HeuristicRollbackException
	{
		userTransaction.begin();
		
		ElectoralAuthorityEntity entity = new ElectoralAuthorityEntity();
		entity.setElectionEventId(ELECTION_EVENT_ID);
		entity.setElectoralAuthorityId(ELECTORAL_AUTHORITY_ID);
		entity.setTenantId(TENANT_ID);
		entity.setJson(ELECTORAL_AUTHORITY_JSON);
		entityManager.persist(entity);
		
		userTransaction.commit();
	}

}
