package com.avaya.zephyr.services.helloservice;

import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Matchers.isA;

import org.junit.Before;
import org.junit.Test;

import com.avaya.collaboration.businessdata.api.NoAttributeFoundException;
import com.avaya.collaboration.businessdata.api.NoServiceProfileFoundException;
import com.avaya.collaboration.businessdata.api.NoUserFoundException;
import com.avaya.collaboration.businessdata.api.ServiceData;
import com.avaya.collaboration.businessdata.api.ServiceNotFoundException;
import com.avaya.collaboration.call.Call;
import com.avaya.collaboration.call.Participant;
import com.avaya.collaboration.util.logger.Logger;

public class HelloServiceListenerTest
{

    private Logger log;
    private ServiceData svcData;
    private Call call;
    private Participant callingParty, calledParty;

    @Before
    public void setUpMocks()
    {
        log = mock(Logger.class);
        svcData = mock(ServiceData.class);
        call = mock(Call.class);
        callingParty = mock(Participant.class);
        calledParty = mock(Participant.class);

        when(callingParty.getHandle()).thenReturn("8300");
        when(callingParty.getDomain()).thenReturn("dr.avaya.com");
        when(callingParty.getAddress()).thenReturn("8300@dr.avaya.com");
        when(calledParty.getHandle()).thenReturn("8301");
        when(calledParty.getDomain()).thenReturn("dr.avaya.com");
        when(calledParty.getAddress()).thenReturn("8301@dr.avaya.com");
        when(call.getCallingParty()).thenReturn(callingParty);
        when(call.getCalledParty()).thenReturn(calledParty);
    }

    @Test
    public void TestWithAttribute() throws NoUserFoundException, ServiceNotFoundException,
            NoAttributeFoundException, NoServiceProfileFoundException
    {
        when(svcData.getServiceAttribute(anyString(), anyString())).thenReturn("Hello world string");
        when(call.isCallingPhase()).thenReturn(true);
        HelloServiceListener hsl = new HelloServiceListener(svcData, log);
        hsl.callIntercepted(call);

        verify(svcData).getServiceAttribute("8300@dr.avaya.com", "displayString");
        verify(callingParty).setPresentedDisplayName("Hello world string");
    }

    @Test
    public void TestWithAttributeCalled() throws NoUserFoundException, ServiceNotFoundException,
            NoAttributeFoundException, NoServiceProfileFoundException
    {
        when(svcData.getServiceAttribute(anyString(), anyString())).thenReturn("Hello world string");
        when(call.isCallingPhase()).thenReturn(false);
        HelloServiceListener hsl = new HelloServiceListener(svcData, log);
        hsl.callIntercepted(call);

        verify(svcData).getServiceAttribute("8301@dr.avaya.com", "displayString");
        verify(callingParty).setPresentedDisplayName("Hello world string");
    }

    @Test
    public void TestWithoutAttribute() throws NoUserFoundException, ServiceNotFoundException,
            NoAttributeFoundException, NoServiceProfileFoundException
    {
        when(svcData.getServiceAttribute(anyString(), anyString())).thenReturn(null);
        when(call.isCallingPhase()).thenReturn(true);

        HelloServiceListener hsl = new HelloServiceListener(svcData, log);
        hsl.callIntercepted(call);

        verify(svcData).getServiceAttribute("8300@dr.avaya.com", "displayString");
        verify(callingParty).setPresentedDisplayName(HelloServiceListener.DEFAULT_DISPLAY);
    }

    @Test
    public void TestAttributeLookupThrowsException() throws NoUserFoundException, NoAttributeFoundException,
            ServiceNotFoundException, NoServiceProfileFoundException
    {
        when(svcData.getServiceAttribute(anyString(), anyString())).thenThrow(
                new NoUserFoundException("ERROR"));
        HelloServiceListener hsl = new HelloServiceListener(svcData, log);
        hsl.callIntercepted(call);
        verify(log, atLeastOnce()).error(anyString(), isA(Exception.class));
    }
}
