package test.org.mule.mep;

import org.mule.api.ExceptionPayload;
import org.mule.api.MessagingException;
import org.mule.api.MuleMessage;
import org.mule.module.client.MuleClient;
import org.mule.transport.NullPayload;

import test.org.mule.routing.MessageReceiver;
import test.org.mule.tck.FunctionalTestCase;

public class InOnlyOutOnlyTest extends FunctionalTestCase {

    static final String URL = "vm://InOnlyOutOnly";
    static final String OUTBOUND_URL = "vm://OutOnly";

    static final long TIMEOUT = 3000;
    static final long SHORT_TIMEOUT = 500;

    protected String getConfigResources() {
        return "test/org/mule/mep/InOnlyOutOnlyTest-config.xml";
    }

    public void testSend_OK() throws Exception {
        MuleClient client = new MuleClient();
        MuleMessage message = client.send(URL, "abc", null);
        assertEquals("abc", message.getPayload());
        MuleMessage result = client.request(OUTBOUND_URL, TIMEOUT);
        assertEquals("abc", result.getPayload());
    }

    public void testSend_FailureAtInterceptor() throws Exception {
        MuleClient client = new MuleClient();
        MuleMessage message = client.send(URL, "failure@interceptor", null);
        assertEquals("FAILURE!! (@interceptor)", message.getPayload());
        MuleMessage result = client.request(OUTBOUND_URL, TIMEOUT);
        assertEquals("FAILURE!! (@interceptor)", result.getPayload());
    }

    public void testSend_FailureAtComponent() throws Exception {
        MuleClient client = new MuleClient();
        MuleMessage message = client.send(URL, "failure@component", null);
        assertEquals("FAILURE!! (@component)", message.getPayload());
        MuleMessage result = client.request(OUTBOUND_URL, TIMEOUT);
        assertEquals("FAILURE!! (@component)", result.getPayload());
    }

    public void testSend_ExceptionAtInterceptor() throws Exception {
        MuleClient client = new MuleClient();
        MuleMessage message = client.send(URL, "exception@interceptor", null);
        assertEquals(NullPayload.getInstance(), message.getPayload());
        ExceptionPayload ep = message.getExceptionPayload();
        MessagingException me = (MessagingException) ep.getException();
        RuntimeException re = (RuntimeException) me.getCause();
        assertEquals("EXCEPTION!! (@interceptor)", re.getMessage());
        assertNull(client.request(OUTBOUND_URL, SHORT_TIMEOUT));
    }

    public void testSend_ExceptionAtComponent() throws Exception {
        MuleClient client = new MuleClient();
        MuleMessage message = client.send(URL, "exception@component", null);
        assertEquals(NullPayload.getInstance(), message.getPayload());
        ExceptionPayload ep = message.getExceptionPayload();
        MessagingException me = (MessagingException) ep.getException();
        RuntimeException re = (RuntimeException) me.getCause();
        assertEquals("EXCEPTION!! (@component)", re.getMessage());
        assertNull(client.request(OUTBOUND_URL, SHORT_TIMEOUT));
    }

    public void testDispatch_OK() throws Exception {
        MuleClient client = new MuleClient();
        MessageReceiver receiver = new MessageReceiver(client);
        client.dispatch(URL, "abc", null);
        assertEquals("abc", receiver.get(TIMEOUT));
        MuleMessage result = client.request(OUTBOUND_URL, TIMEOUT);
        assertEquals("abc", result.getPayload());
    }

    public void testDispatch_FailureAtInterceptor() throws Exception {
        MuleClient client = new MuleClient();
        MessageReceiver receiver = new MessageReceiver(client);
        client.dispatch(URL, "failure@interceptor", null);
        assertEquals("FAILURE!! (@interceptor)", receiver.get(TIMEOUT));
        MuleMessage result = client.request(OUTBOUND_URL, TIMEOUT);
        assertEquals("FAILURE!! (@interceptor)", result.getPayload());
    }

    public void testDispatch_FailureAtComponent() throws Exception {
        MuleClient client = new MuleClient();
        MessageReceiver receiver = new MessageReceiver(client);
        client.dispatch(URL, "failure@component", null);
        assertEquals("FAILURE!! (@component)", receiver.get(TIMEOUT));
        MuleMessage result = client.request(OUTBOUND_URL, TIMEOUT);
        assertEquals("FAILURE!! (@component)", result.getPayload());
    }

    public void testDispatch_ExceptionAtInterceptor() throws Exception {
        MuleClient client = new MuleClient();
        MessageReceiver receiver = new MessageReceiver(client);
        client.dispatch(URL, "exception@interceptor", null);
        try {
            receiver.get(TIMEOUT);
            fail();
        } catch (RuntimeException e) {
            assertEquals("EXCEPTION!! (@interceptor)", e.getMessage());
        }
        assertNull(client.request(OUTBOUND_URL, SHORT_TIMEOUT));
    }

    public void testDispatch_ExceptionAtComponent() throws Exception {
        MuleClient client = new MuleClient();
        MessageReceiver receiver = new MessageReceiver(client);
        client.dispatch(URL, "exception@component", null);
        try {
            receiver.get(TIMEOUT);
            fail();
        } catch (RuntimeException e) {
            assertEquals("EXCEPTION!! (@component)", e.getMessage());
        }
        assertNull(client.request(OUTBOUND_URL, SHORT_TIMEOUT));
    }

}
