package be.ehealth.technicalconnector.service.keydepot;

import java.security.GeneralSecurityException;
import java.util.ArrayList;
import java.util.List;

import org.junit.Assert;
import org.junit.ClassRule;
import org.junit.Test;

import be.ehealth.technicalconnector.exception.TechnicalConnectorException;
import be.ehealth.technicalconnector.service.ServiceFactory;
import be.ehealth.technicalconnector.service.etee.domain.EncryptionToken;
import be.fgov.ehealth.etkdepot._1_0.protocol.GetEtkRequest;
import be.fgov.ehealth.etkdepot._1_0.protocol.GetEtkResponse;
import be.fgov.ehealth.etkdepot._1_0.protocol.IdentifierType;
import be.fgov.ehealth.etkdepot._1_0.protocol.SearchCriteriaType;
import be.fgov.ehealth.technicalconnector.tests.junit.rule.SessionRule;
import be.fgov.ehealth.technicalconnector.tests.utils.AssertTools;

/**
 * Key Depot Service Integration Tests This test shows the use of the Key Depot Service through the use of the Technical Connector
 * 
 * @author EHP
 */
public class KeyDepotServiceIntegrationTest {

    @ClassRule
    public static SessionRule rule = SessionRule.withActiveSession().build();

    /**
     * Test the getEtk operation from the ETK Service through the use of the Technical Connector
     * 
     * The getEtk methods needs the following parameters: - application name - type of the identifier - value of the identifier
     * 
     * @author EHP
     */
    @Test
    public void testGetEtk() throws Exception {
        /*
         * Set the values to use in this test
         */
        // The application name (retrieved from config file)
        String applicationName = rule.getSessionProperty("test.myEtk.app");
        // The type of the identifier (linked to value, retrieved from config file)
        String type = rule.getSessionProperty("test.myEtk.type");
        // the value linked to the typed (retrieved from config file)
        String value = rule.getSessionProperty("test.myEtk.value");


        /*
         * Create request
         */
        // create etk request
        GetEtkRequest request = new GetEtkRequest();
        // create the search criteria
        SearchCriteriaType searchCriteria = new SearchCriteriaType();
        // the request expects a list of identifiers to get the ETK for.
        // in this example we will provide a list with 1 item.
        List<IdentifierType> listIdentifiers = new ArrayList<IdentifierType>();
        // create the identifier
        IdentifierType identifier = new IdentifierType();
        // set the application name
        identifier.setApplicationID(applicationName);
        // set the type (e.g. CBE)
        identifier.setType(type);
        // set the value associated with the type
        identifier.setValue(value);
        // add the identifier to the list
        listIdentifiers.add(createIdentifier(value, type, applicationName));
        // add the list to the search criteria
        searchCriteria.getIdentifiers().addAll(listIdentifiers);
        // add the search criteria to the request
        request.setSearchCriteria(searchCriteria);

        invokeKeyDepot(request);
    }

    private void invokeKeyDepot(GetEtkRequest request) throws TechnicalConnectorException, GeneralSecurityException {
        /*
         * Invoke the technical connector framework's ETK Service's getEtk operation
         */
        KeyDepotService service = ServiceFactory.getKeyDepotService();
        GetEtkResponse response = service.getETK(request);

        /*
         * Verify the response
         */
        // check if the status is ok
        Assert.assertEquals("200", response.getStatus().getCode());
        // check the ETK is received
        Assert.assertNotNull(response.getETK());
        EncryptionToken token = new EncryptionToken(response.getETK());
        AssertTools.assertEncryptionToken(token);
    }


    private IdentifierType createIdentifier(String value, String type, String applicationId) {
        IdentifierType identifier = new IdentifierType();
        identifier.setApplicationID(applicationId);
        identifier.setType(type);
        identifier.setValue(value);
        return identifier;
    }
}
