/*
 * Copyright (c) eHealth
 */
package be.ehealth.technicalconnector.ws;

import java.net.URI;

import javax.activation.DataHandler;

import org.apache.commons.lang3.StringUtils;
import org.junit.Assert;
import org.junit.Rule;
import org.junit.Test;

import be.ehealth.technicalconnector.handler.SchemaValidatorHandler;
import be.ehealth.technicalconnector.handler.domain.WsAddressingHeader;
import be.ehealth.technicalconnector.jaxb.AttachmentRoot;
import be.ehealth.technicalconnector.utils.ByteArrayDatasource;
import be.ehealth.technicalconnector.ws.domain.GenericRequest;
import be.ehealth.technicalconnector.ws.domain.HandlerChain;
import be.ehealth.technicalconnector.ws.domain.HandlerPosition;
import be.ehealth.technicalconnector.ws.feature.GenericFeature;
import be.ehealth.technicalconnector.ws.feature.XOPFeature;
import be.fgov.ehealth.technicalconnector.tests.junit.rule.HttpServerStubRule;
import be.fgov.ehealth.technicalconnector.tests.server.EchoResponse;
import be.fgov.ehealth.technicalconnector.tests.server.EchoResponse.Inbound;

/**
 * @author eHealth Platform (EHP)
 *
 */
public class GenericWsSenderTest {

    private static final String PAYLOAD = "postData";

    @Rule
    public HttpServerStubRule server = new HttpServerStubRule();

    @Test
    public void validateXOP() throws Exception {
        AttachmentRoot content = new AttachmentRoot();
        content.setContentInline("contentInLine".getBytes());
        HandlerChain chain = new HandlerChain();
        chain.register(HandlerPosition.BEFORE, new SchemaValidatorHandler(SchemaValidatorHandler.VERIFY_OUTBOUND, "/be/ehealth/technicalconnector/jaxb/AttachmentRoot.xsd"));
        invoke(new GenericRequest().setPayload(content, new XOPFeature(5)).setHandlerChain(chain));
    }

    @Test
    public void inboundXOP() throws Exception {
        server.add("/full/mtom", "/stub/xop_with_special_contentid.xml");

        GenericRequest req = new GenericRequest()//
            .setPayload(new AttachmentRoot())//
            .setEndpoint(server.getContentUrl("/full/mtom"));

        AttachmentRoot actual = ServiceFactory.getGenericWsSender().send(req).asObject(AttachmentRoot.class);
        Assert.assertEquals("xop is my friend!", new String(actual.getContentInline()));
    }

    @Test
    public void inboundEmptyXOP() throws Exception {
        server.add("/full/mtom", "/stub/xop_empty_content.xml");

        GenericRequest req = new GenericRequest()//
            .setPayload(new AttachmentRoot())//
            .setEndpoint(server.getContentUrl("/full/mtom"));

        AttachmentRoot actual = ServiceFactory.getGenericWsSender().send(req).asObject(AttachmentRoot.class);
        Assert.assertEquals("", new String(actual.getContentInline()));
    }

    @Test
    public void soapAction() throws Exception {
        GenericRequest req = new GenericRequest()//
            .setPayload(new AttachmentRoot())//
            .setSoapAction("soapAction:rocks");

        Assert.assertEquals("soapAction:rocks", invoke(req).getHeaders().get("soapaction"));

    }

    @Test
    public void userAgent() throws Exception {
        GenericRequest req = new GenericRequest()//
            .setPayload(new AttachmentRoot())//
            .setSoapAction("verify:user-agent");
        Assert.assertTrue(invoke(req).getHeaders().get("user-agent").startsWith("Ehealth Technical ("));
    }


    @Test
    public void outboundXOPThresholdExceed() throws Exception {
        AttachmentRoot content = new AttachmentRoot();
        content.setContentInline("contentInLine".getBytes());
        String payload = invoke(new GenericRequest().setPayload(content, new XOPFeature(5))).getFiles().get(PAYLOAD);
        Assert.assertTrue(StringUtils.contains(payload, "@ehealth.fgov.be\"/></ContentInline>"));
        Assert.assertTrue(StringUtils.contains(payload,"Content-Transfer-Encoding: binary"));
        Assert.assertTrue(StringUtils.contains(payload,"Content-ID: <"));
    }

    @Test
    public void outboundXOPThresholdNotExceed() throws Exception {
        AttachmentRoot content = new AttachmentRoot();
        content.setContentInline("contentInLine".getBytes());
        String payload = invoke(new GenericRequest().setPayload(content, new XOPFeature(25))).getFiles().get(PAYLOAD);
        Assert.assertTrue(StringUtils.contains(payload, "Y29udGVudEluTGluZQ=="));
    }

    @Test
    public void inline() throws Exception {
        AttachmentRoot content = new AttachmentRoot();
        content.setContentInline("contentInLine".getBytes());
        String payload = invoke(new GenericRequest().setPayload(content, (GenericFeature) null)).getFiles().get(PAYLOAD);
        Assert.assertTrue(StringUtils.contains(payload, "Y29udGVudEluTGluZQ=="));
    }

    @Test
    public void swaref() throws Exception {
        AttachmentRoot content = new AttachmentRoot();
        content.setContentAsRef(new DataHandler(new ByteArrayDatasource("contentAsRef".getBytes())));
        String payload = invoke(new GenericRequest().setPayload(content, (GenericFeature) null)).getFiles().get(PAYLOAD);
        Assert.assertTrue(StringUtils.contains(payload, "@ehealth.fgov.be</ContentAsRef>"));
    }

    @Test
    public void wsAddressing() throws Exception {
        AttachmentRoot content = new AttachmentRoot();
        String payload = invoke(new GenericRequest().setPayload(content).setWSAddressing(new WsAddressingHeader(new URI("urn:be:fgov:ehealth:wsaddressing")))).getFiles().get(PAYLOAD);
        Assert.assertTrue(StringUtils.contains(payload, "http://www.w3.org/2005/08/addressing"));
        Assert.assertTrue(StringUtils.contains(payload, "Action"));
        Assert.assertTrue(StringUtils.contains(payload, "urn:be:fgov:ehealth:wsaddressing"));
        Assert.assertTrue(StringUtils.contains(payload, "mustUnderstand=\"1\""));
    }

    private Inbound invoke(GenericRequest req) throws Exception {
        req.setEndpoint(server.getEchoUrl());
        return ServiceFactory.getGenericWsSender().send(req).asObject(EchoResponse.class).getInbound();
    }


}
