package be.ehealth.technicalconnector.handler;

import javax.xml.soap.MessageFactory;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPMessage;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.handler.soap.SOAPMessageContext;

import org.junit.After;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;

import be.ehealth.technicalconnector.config.ConfigFactory;
import be.ehealth.technicalconnector.exception.TechnicalConnectorException;
import be.ehealth.technicalconnector.utils.ConnectorIOUtils;
import be.ehealth.technicalconnector.utils.ConnectorXmlUtils;
import be.ehealth.technicalconnector.ws.impl.SOAPMessageContextImpl;
import be.ehealth.technicalconnector.ws.impl.strategy.RetryStrategy;
import be.fgov.ehealth.technicalconnector.tests.utils.LoggingUtils;

public class MessageLevelRetryHandlerTest {
    @BeforeClass
    public static void before() {
        LoggingUtils.bootstrap();
        RetryStrategy.RetryNotifier.reset();
    }

    @After
    public void after() {
        RetryStrategy.RetryNotifier.reset();
    }

    @Test
    public void soapFaultSwitchDesActivated() throws Exception {

        ConfigFactory.getConfigValidator().setProperty(MessageLevelRetryHandler.PROP_MESSAGELEVEL_RETRY_ACTIVATED, "false");

        String body = ConnectorIOUtils.getResourceAsString("/examples/soap/soapFault.SystemError.SOA01001.xml");

        SOAPMessageContext context = generate(body);

        boolean result = new MessageLevelRetryHandler().handleMessage(context);
        Assert.assertFalse(RetryStrategy.RetryNotifier.activated());
        Assert.assertTrue(result);
    }

    @Test
    public void soapFaultSwitchActivatedTriggered() throws Exception {
        ConfigFactory.getConfigValidator().setProperty(MessageLevelRetryHandler.PROP_MESSAGELEVEL_RETRY_ACTIVATED, "true");

        String body = ConnectorIOUtils.getResourceAsString("/examples/soap/soapFault.SystemError.SOA01001.xml");

        SOAPMessageContext context = generate(body);

        boolean result = new MessageLevelRetryHandler().handleMessage(context);

        Assert.assertTrue(RetryStrategy.RetryNotifier.activated());
        Assert.assertTrue(result);


    }


    @Test
    public void soapFaultSwitchActivatedNotTriggered() throws Exception {

        ConfigFactory.getConfigValidator().setProperty(MessageLevelRetryHandler.PROP_MESSAGELEVEL_RETRY_ACTIVATED, "true");

        String body = ConnectorIOUtils.getResourceAsString("/examples/soap/soapFault.SystemError.SOA03006.xml");

        SOAPMessageContext context = generate(body);

        boolean result = new MessageLevelRetryHandler().handleMessage(context);
        Assert.assertFalse(RetryStrategy.RetryNotifier.activated());
        Assert.assertTrue(result);
    }

    private static SOAPMessageContext generate(String body) throws SOAPException, TechnicalConnectorException {
        MessageFactory mf = MessageFactory.newInstance();
        SOAPMessage soapMessage = mf.createMessage();
        soapMessage.getSOAPBody()
                .addDocument(ConnectorXmlUtils.toDocument(body));

        SOAPMessageContext context = new SOAPMessageContextImpl(soapMessage);

        context.put(MessageContext.MESSAGE_OUTBOUND_PROPERTY, Boolean.FALSE);
        return context;
    }
}