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

import java.util.Properties;

import org.joda.time.DateTime;
import org.junit.Assert;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import be.ehealth.businessconnector.genins.builders.RequestObjectBuilderFactory;
import be.ehealth.businessconnector.genins.domain.RequestParameters;
import be.ehealth.businessconnector.genins.service.ServiceFactory;
import be.ehealth.technicalconnector.exception.TechnicalConnectorException;
import be.ehealth.technicalconnector.idgenerator.IdGeneratorFactory;
import be.ehealth.technicalconnector.utils.ConnectorIOUtils;
import be.ehealth.technicalconnector.utils.ConnectorXmlUtils;
import be.ehealth.technicalconnector.validator.ValidatorHelper;
import be.ehealth.technicalconnector.validator.impl.EhealthReplyValidatorImpl;
import be.fgov.ehealth.genericinsurability.core.v1.InsurabilityContactTypeType;
import be.fgov.ehealth.genericinsurability.core.v1.InsurabilityRequestTypeType;
import be.fgov.ehealth.genericinsurability.core.v1.MessageFaultType;
import be.fgov.ehealth.genericinsurability.protocol.v1.GetInsurabilityAsXmlOrFlatRequestType;
import be.fgov.ehealth.genericinsurability.protocol.v1.GetInsurabilityResponse;

/**
 * @author EH053
 */
public abstract class AbstractGenInsIntegrationTest {

    private static Properties testProps = new Properties();

    private static final Logger LOG = LoggerFactory.getLogger(AbstractGenInsIntegrationTest.class);

    protected static boolean isTest = false;

    static {
        try {
            testProps.load(ConnectorIOUtils.getResourceAsStream("/be.ehealth.businessconnector.genins.test.properties"));
        } catch (Exception e) {
            throw new IllegalArgumentException(e);
        }
    }

    @Test
    public void testOA100() throws Exception {

        long time1 = System.currentTimeMillis();
        getInsurabilityTest(testProps.getProperty("test.patient.oa100"), null, null, InsurabilityRequestTypeType.INFORMATION);
        LOG.error("_____________________________________________SECOND RUN_____________________________________________________");
        long time2 = System.currentTimeMillis();
        getInsurabilityTest(testProps.getProperty("test.patient.oa100"), null, null, InsurabilityRequestTypeType.INFORMATION);
        long time3 = System.currentTimeMillis();
        LOG.error("_____________________________________________FINISHED : (firstrun:" + (time2 - time1) + ", second run:" + (time3 - time2) + " _____________________________________________________");
    }

    @Test
    public void testOA300() throws Exception {


        getInsurabilityTest(testProps.getProperty("test.patient.oa300"), null, null, InsurabilityRequestTypeType.INFORMATION);
    }

    @Test
    public void testOA500() throws Exception {
        getInsurabilityTest(testProps.getProperty("test.patient.oa500"), null, null, InsurabilityRequestTypeType.INFORMATION);
    }

    private void getInsurabilityTest(String inss, String mutuality, String regnrWithMut, InsurabilityRequestTypeType insurabilityRequestTypeType) throws Exception {
        getInsurabilityTest(inss, mutuality, regnrWithMut, insurabilityContactType(testProps.getProperty("session.professionType")), insurabilityRequestTypeType);
    }

    private void getInsurabilityTest(String inss, String mutuality, String regnrWithMut, InsurabilityContactTypeType insurabilityContactTypeType, InsurabilityRequestTypeType insurabilityRequestTypeType) throws Exception {

        RequestParameters requestParameters = new RequestParameters();
        requestParameters.setInss(inss);
        requestParameters.setMutuality(mutuality);
        requestParameters.setRegNrWithMut(regnrWithMut);
        DateTime dateTime = new DateTime();
        requestParameters.setPeriodStart(dateTime);
        requestParameters.setPeriodEnd(dateTime);
        requestParameters.setInsurabilityReference(IdGeneratorFactory.getIdGenerator().generateId());
        requestParameters.setInsurabilityContactType(insurabilityContactTypeType);
        requestParameters.setInsurabilityRequestType(insurabilityRequestTypeType);

        GetInsurabilityAsXmlOrFlatRequestType request = RequestObjectBuilderFactory.getRequestObjectBuilder().createGetInsurabilityRequest(requestParameters, isTest);

        GetInsurabilityResponse response = invoke(request);

        // Validate against XSD
        ValidatorHelper.validate(response, response.getClass(), ServiceFactory.GENINS_XSD[0]);
        // Verify EHealth STATUS
        new EhealthReplyValidatorImpl().validateReplyStatus(response);
        // Verify that the message doesn't contains a messagefault.
        MessageFaultType messageFault = response.getResponse().getMessageFault();
        ConnectorXmlUtils.logXmlObject(messageFault);
        Assert.assertNull("MessageFault <> null;", messageFault);

    }

    public static InsurabilityContactTypeType insurabilityContactType(String quality) throws TechnicalConnectorException {
        if ("persphysician".equals(quality)) {
            return InsurabilityContactTypeType.AMBULATORY_CARE;
        } else {
            return InsurabilityContactTypeType.OTHER;
        }
    }

    protected abstract GetInsurabilityResponse invoke(GetInsurabilityAsXmlOrFlatRequestType request) throws Exception;

}