package com.avaya.zephyr.services.multichanbroadcast.announcementcall;

import static org.easymock.EasyMock.expect;
import static org.powermock.api.easymock.PowerMock.createMock;
import static org.powermock.api.easymock.PowerMock.expectLastCall;
import static org.powermock.api.easymock.PowerMock.replayAll;
import static org.powermock.api.easymock.PowerMock.verifyAll;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

import com.avaya.collaboration.call.Call;
import com.avaya.collaboration.call.CallTerminationCause;
import com.avaya.collaboration.call.Participant;
import com.avaya.collaboration.util.logger.Logger;

@RunWith(PowerMockRunner.class)
@PrepareForTest(
{ MultiChanBroadcastCallListener.class, CallTerminationCause.class })
public class MultiChanBroadcastCallListenerTest
{
    private static final String CALLANSWERED_LOG_INVOKED =
            "callAnswered invoked. Attempting to play announcement to ";
    private static final String CALLTERMINATED_LOG_INVOKED = "callTerminated invoked for call to ";
    private static final String CALLTERMINATED_LOG_DTMF_NOT_ACK =
            "callTerminated: DTMF NOT acknowledged for call to ";
    private static final String CALLTERMINATED_LOG_NO_CALL = "callTerminated invoked with null call";
    private static final String CALL_ATTRIBUTE_DIGITSCOLLECTED = "digitsCollected";
    private MultiChanBroadcastCallListener multiChanBroadcastCallListenerTest;
    private MultiChanBroadcastMediaListener mockMultiChanBroadcastMediaListener;
    private Logger mockLogger;
    private Call mockCall;
    private Participant mockParticipant;
    private CallTerminationCause mockCallTerminationCause;

    @Before
    public void setUp() throws Exception
    {
        mockLogger = createMock(Logger.class);
        mockCall = createMock(Call.class);
        mockCallTerminationCause = createMock(CallTerminationCause.class);
        mockParticipant = createMock(Participant.class);
        mockMultiChanBroadcastMediaListener = createMock(MultiChanBroadcastMediaListener.class);
        multiChanBroadcastCallListenerTest =
                new MultiChanBroadcastCallListener(mockLogger, mockMultiChanBroadcastMediaListener);
    }

    @Test
    public void testCallAnswered() throws Exception
    {
        // Test Info

        // Test Data

        // Setup mocks
        expect(mockCall.getAnsweringParty()).andReturn(mockParticipant);
        expect(mockParticipant.getAddress()).andReturn("");
        mockLogger.info(CALLANSWERED_LOG_INVOKED);
        expectLastCall();
        mockMultiChanBroadcastMediaListener.playAnnouncementAndCollectDigits(mockCall);
        expectLastCall();

        // Replay, Execute, and Verify
        replayAll();
        multiChanBroadcastCallListenerTest.callAnswered(mockCall);
        verifyAll();
    }

    @Test
    public void testCallTerminatedNullCall() throws Exception
    {
        // Test Info

        // Test Data

        // Setup mocks
        mockLogger.error(CALLTERMINATED_LOG_NO_CALL);
        expectLastCall();

        // Replay, Execute, and Verify
        replayAll();
        multiChanBroadcastCallListenerTest.callTerminated(null, mockCallTerminationCause);
        verifyAll();
    }

    @Test
    public void testCallTerminatedWithCauseNonNullDigitsCollected() throws Exception
    {
        // Test Info

        // Test Data
        final String mockAddress = "555@domain.com";
        final String mockCause = "mockCause";

        // Setup mocks
        mockMultiChanBroadcastMediaListener.callTerminated(mockCall);
        expect(mockCall.getCalledParty()).andReturn(mockParticipant);
        expect(mockParticipant.getAddress()).andReturn(mockAddress);
        expect(mockCallTerminationCause.getValue()).andReturn(mockCause);
        mockLogger.info(CALLTERMINATED_LOG_INVOKED + mockAddress +
                " with cause " + mockCause);
        expectLastCall();
        expect(
                mockCall.getAttribute(CALL_ATTRIBUTE_DIGITSCOLLECTED))
                .andReturn(true).anyTimes();

        // Replay, Execute, and Verify
        replayAll();
        multiChanBroadcastCallListenerTest.callTerminated(mockCall, mockCallTerminationCause);
        verifyAll();
    }

    @Test
    public void testCallTerminatedWithCauseNullDigitsCollected() throws Exception
    {
        // Test Info

        // Test Data
        final String mockAddress = "555@domain.com";
        final String mockCause = "mockCause";

        // Setup mocks
        mockMultiChanBroadcastMediaListener.callTerminated(mockCall);
        expectLastCall();
        expect(mockCall.getCalledParty()).andReturn(mockParticipant);
        expect(mockParticipant.getAddress()).andReturn(mockAddress).anyTimes();
        expect(mockCallTerminationCause.getValue()).andReturn(mockCause);
        mockLogger.info(CALLTERMINATED_LOG_INVOKED + mockAddress +
                " with cause " + mockCause);
        expectLastCall();
        expect(
                mockCall.getAttribute(CALL_ATTRIBUTE_DIGITSCOLLECTED))
                .andReturn(null).anyTimes();
        mockLogger.info(CALLTERMINATED_LOG_DTMF_NOT_ACK + mockAddress);
        expectLastCall();

        // Replay, Execute, and Verify
        replayAll();
        multiChanBroadcastCallListenerTest.callTerminated(mockCall, mockCallTerminationCause);
        verifyAll();
    }

    @Test
    public void testCallTerminatedWithCauseFalseDigitsCollected() throws Exception
    {
        // Test Info

        // Test Data
        final String mockAddress = "555@domain.com";
        final String mockCause = "mockCause";

        // Setup mocks
        mockMultiChanBroadcastMediaListener.callTerminated(mockCall);
        expect(mockCall.getCalledParty()).andReturn(mockParticipant);
        expect(mockParticipant.getAddress()).andReturn(mockAddress).anyTimes();
        expect(mockCallTerminationCause.getValue()).andReturn(mockCause);
        mockLogger.info(CALLTERMINATED_LOG_INVOKED + mockAddress +
                " with cause " + mockCause);
        expectLastCall();
        expect(
                mockCall.getAttribute(CALL_ATTRIBUTE_DIGITSCOLLECTED))
                .andReturn(false).anyTimes();
        mockLogger.info(CALLTERMINATED_LOG_DTMF_NOT_ACK + mockAddress);
        expectLastCall();

        // Replay, Execute, and Verify
        replayAll();
        multiChanBroadcastCallListenerTest.callTerminated(mockCall, mockCallTerminationCause);
        verifyAll();
    }

    @Test
    public void testCallTerminatedNullCalledPartyNullCauseFalseDigitsCollected() throws Exception
    {
        // Test Info

        // Test Data
        final String mockAddress = null;
        final String mockCause = null;

        // Setup mocks
        mockMultiChanBroadcastMediaListener.callTerminated(mockCall);
        expectLastCall();
        expect(mockCall.getCalledParty()).andReturn(mockParticipant);
        expect(mockParticipant.getAddress()).andReturn(mockAddress).anyTimes();
        expect(mockCallTerminationCause.getValue()).andReturn(mockCause);
        mockLogger.info(CALLTERMINATED_LOG_INVOKED + mockAddress +
                " with cause " + mockCause);
        expectLastCall();
        expect(
                mockCall.getAttribute(CALL_ATTRIBUTE_DIGITSCOLLECTED))
                .andReturn(false).anyTimes();
        mockLogger.info(CALLTERMINATED_LOG_DTMF_NOT_ACK + mockAddress);
        expectLastCall();

        // Replay, Execute, and Verify
        replayAll();
        multiChanBroadcastCallListenerTest.callTerminated(mockCall, mockCallTerminationCause);
        verifyAll();
    }

}
