/*
 * Copyright (c) eHealth
 */
package be.ehealth.businessconnector.ssinhistory;

import java.util.Properties;

import org.joda.time.DateTime;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.ClassRule;
import org.junit.Test;

import be.ehealth.businessconnector.ssinhistory.session.SsinHistorySessionService;
import be.ehealth.businessconnector.ssinhistory.session.SsinHistorySessionServiceFactory;
import be.ehealth.technicalconnector.exception.SoaErrorException;
import be.ehealth.technicalconnector.exception.TechnicalConnectorException;
import be.fgov.ehealth.consultrn.ssinhistory.protocol.v1.ConsultCurrentSsinRequest;
import be.fgov.ehealth.consultrn.ssinhistory.protocol.v1.ConsultCurrentSsinResponse;
import be.fgov.ehealth.consultrn.ssinhistory.protocol.v1.ConsultRelatedSsinsRequest;
import be.fgov.ehealth.consultrn.ssinhistory.protocol.v1.ConsultRelatedSsinsResponse;
import be.fgov.ehealth.technicalconnector.tests.junit.rule.SessionRule;
import be.fgov.ehealth.technicalconnector.tests.utils.TestPropertiesLoader;

/**
 * @author EHP
 */
public class SsinHistoryIntegrationTest {

    @ClassRule
    public static SessionRule rule = SessionRule.withActiveSession().baseOn("/be.ehealth.businessconnector.ssinhistory.test.properties").build();

    private static Properties props;

    private static SsinHistorySessionService service;

    @BeforeClass
    public static void init() throws Exception {
        props = TestPropertiesLoader.getProperties("/be.ehealth.businessconnector.ssinhistory.test.properties");
        service = SsinHistorySessionServiceFactory.getSsinHistorySessionService();
    }

    @Test
    public void consultRelatedSsinsValidTest() throws Exception {
        ConsultRelatedSsinsResponse response = consultRelatedSsins(props.getProperty("test.valid.ssin"));
        checkSuccessRelatedSsins(response);
    }

    @Test
    public void consultCurrentSsinValidTest() throws Exception {
        ConsultCurrentSsinResponse response = consultCurrentSsin(props.getProperty("test.valid.ssin"));
        checkSuccessCurrentSsin(response);
    }

    @Test
    public void consultRelatedSsinsCancelledTest() throws Exception {
        ConsultRelatedSsinsResponse response = consultRelatedSsins(props.getProperty("test.cancelled.ssin"));
        checkSuccessRelatedSsins(response);
    }

    @Test
    public void consultCurrentSsinCancelledTest() throws Exception {
        ConsultCurrentSsinResponse response = consultCurrentSsin(props.getProperty("test.cancelled.ssin"));
        checkSuccessCurrentSsin(response);
    }

    @Test
    public void consultRelatedSsinsReplacedTest() throws Exception {
        ConsultRelatedSsinsResponse response = consultRelatedSsins(props.getProperty("test.replaced.ssin"));
        checkSuccessRelatedSsins(response);
    }

    @Test
    public void consultCurrentSsinReplacedTest() throws Exception {
        ConsultCurrentSsinResponse response = consultCurrentSsin(props.getProperty("test.replaced.ssin"));
        checkSuccessCurrentSsin(response);
    }

    @Test(expected = SoaErrorException.class)
    public void consultRelatedSsinsNotExistTest() throws Exception {
        consultRelatedSsins(props.getProperty("test.notexist.ssin"));
    }

    @Test(expected = SoaErrorException.class)
    public void consultCurrentSsinNotExistTest() throws Exception {
        consultCurrentSsin(props.getProperty("test.notexist.ssin"));
    }

    @Test(expected = SoaErrorException.class)
    public void consultRelatedSsinsIncorrectCheckDigitTest() throws Exception {
        consultRelatedSsins("12345678912");
    }

    @Test(expected = SoaErrorException.class)
    public void consultCurrentSsinIncorrectCheckDigitTest() throws Exception {
        consultCurrentSsin("12345678912");
    }

    @Test(expected = SoaErrorException.class)
    public void consultRelatedSsinsIncorrectLengthTest() throws Exception {
        consultRelatedSsins("123");
    }

    @Test(expected = SoaErrorException.class)
    public void consultCurrentSsinIncorrectLengthTest() throws Exception {
        consultCurrentSsin("123");
    }

    @Test(expected = SoaErrorException.class)
    public void consultRelatedSsinsSsinContainsCharTest() throws Exception {
        consultRelatedSsins("abc");
    }

    @Test(expected = SoaErrorException.class)
    public void consultCurrentSsinSsinContainsCharTest() throws Exception {
        consultCurrentSsin("abc");
    }

    @Test(expected = SoaErrorException.class)
    public void consultRelatedSsinsSsinEmptySsinTest() throws Exception {
        consultRelatedSsins("");
    }

    @Test(expected = SoaErrorException.class)
    public void consultCurrentSsinSsinEmptySsinTest() throws Exception {
        consultCurrentSsin("");
    }


    private ConsultRelatedSsinsResponse consultRelatedSsins(String ssin) throws TechnicalConnectorException {
        ConsultRelatedSsinsRequest request = new ConsultRelatedSsinsRequest();
        request.setId("_1");
        request.setIssueInstant(new DateTime());
        request.setSsin(ssin);

        return service.consultRelatedSsins(request);
    }

    private void checkSuccessRelatedSsins(ConsultRelatedSsinsResponse response) {
        Assert.assertEquals("The result is not a succes", "urn:be:fgov:ehealth:2.0:status:Success", response.getStatus().getStatusCode().getValue());
        Assert.assertNull("The result is not a succes", response.getStatus().getStatusCode().getStatusCode());
        Assert.assertTrue("No related ssins in response", response.getRelatedSsins().getRelatedSsins().size() > 0);
    }

    private ConsultCurrentSsinResponse consultCurrentSsin(String ssin) throws TechnicalConnectorException {
        ConsultCurrentSsinRequest request = new ConsultCurrentSsinRequest();
        request.setId("_1");
        request.setIssueInstant(new DateTime());
        request.setSsin(ssin);

        return service.consultCurrentSsinResponse(request);
    }

    private void checkSuccessCurrentSsin(ConsultCurrentSsinResponse response) {
        Assert.assertEquals("The result is not a succes", "urn:be:fgov:ehealth:2.0:status:Success", response.getStatus().getStatusCode().getValue());
        Assert.assertNull("The result is not a succes", response.getStatus().getStatusCode().getStatusCode());
        Assert.assertNotNull("No ssin in response", response.getSsin().getValue());
    }
}
