package com.mockobjects.jms;

import com.mockobjects.*;
import javax.jms.*;

public class MockMessageConsumer extends MockObject implements MessageConsumer{
    private final ReturnValue myMessage = new ReturnValue("message");
    private boolean myExpiresOnTimeout = false;
    private JMSException myException;
    protected ExpectationCounter myCloseCalls =
        new ExpectationCounter("MockMessageConsumer.close");
    protected ExpectationCounter myReceiveCalls =
        new ExpectationCounter("MockMessageConsumer.receive");
    private ExpectationValue messageListener =
        new ExpectationValue("messageListener");
    private final ExpectationValue timeout = new ExpectationValue("timeout");

    public void setExpectedMessageListener(MessageListener messageListener){
        this.messageListener.setExpected(messageListener);
    }

    public void close() throws JMSException {
        throwExceptionIfAny();
        myCloseCalls.inc();
    }

    public MessageListener getMessageListener() throws JMSException {
        notImplemented();
        return null;
    }

    public String getMessageSelector() throws JMSException {
        notImplemented();
        return null;
    }

    public Message receive() throws JMSException {
        throwExceptionIfAny();
        myReceiveCalls.inc();
        if (myExpiresOnTimeout) {
            synchronized(this) {
                try {
                    wait();
                } catch (InterruptedException e) {
                    throw new junit.framework.AssertionFailedError(
                        "Thread interrupted");
                }
            }
        }
        return (Message)myMessage.getValue();
    }

    public Message receive(long timeout) throws JMSException {
        this.timeout.setActual(timeout);
        throwExceptionIfAny();
        myReceiveCalls.inc();
        if (myExpiresOnTimeout) {
            return null;
        } else {
            return (Message)myMessage.getValue();
        }
    }

    public void setExpectedTimeout(long timeout){
        this.timeout.setExpected(timeout);
    }

    public Message receiveNoWait() throws JMSException {
        throwExceptionIfAny();
        myReceiveCalls.inc();
        return (Message)myMessage.getValue();
    }

    public void setExpectedCloseCalls(int callCount) {
        myCloseCalls.setExpected(callCount);
    }

    public void setExpectedReceiveCalls(int callCount) {
        myReceiveCalls.setExpected(callCount);
    }

    public void setupReceivedMessage(Message message) {
        myMessage.setValue(message);
    }

    public void setupExpiresOnTimeout(boolean expiresOnTimeout) {
        myExpiresOnTimeout = expiresOnTimeout;
    }

    public void setupThrowException(JMSException e) {
        myException = e;
    }

    public void setMessageListener(MessageListener messageListener)
    throws JMSException{
        this.messageListener.setActual(messageListener);
    }

    protected void throwExceptionIfAny() throws JMSException {
        if (null != myException) {
            throw myException;
        }
    }
}
