/*****************************************************************************
 * Â© 2015 Avaya Inc. All rights reserved.
 ****************************************************************************/
package com.avaya.zephyr.services.sample_services.ClickToCall;

import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import static org.junit.Assert.assertEquals;
import org.junit.Before;
import org.junit.Test;

import com.avaya.asm.datamgr.DMFactory;
import com.avaya.collaboration.call.Call;
import com.avaya.collaboration.call.Participant;
import com.avaya.collaboration.util.logger.Logger;
import com.avaya.zephyr.platform.dao.ClusterAttributeDAO;

public final class RequestProcessorImplTest
{
    private static final String DOMAIN_DELIMITER_AT = "@";
    private static final String DOMAIN = "avaya.com";
    private static final String FIRST_PARTY = "3403@avaya.com";
    private static final String SECOND_PARTY = "3404@avaya.com";
    private static final String CALLING_ID = "3402@avaya.com";
    private static final String FIRST_PARTY_NO_DOMAIN = "3403";
    private static final String SECOND_PARTY_NO_DOMAIN = "3404";
    private static final String CALLING_ID_NO_DOMAIN = "3402";
    private static final String BODY_FIRST_PARTY_EMPTY = "first=&second=2000@avaya.com&calling=3000@avaya.com&display=DisplayName";
    private static final String BODY_SECOND_PARTY_EMPTY = "first=1000@avaya.com&second=&calling=3000@avaya.com&display=DisplayName";
    private static final String BODY_CALLING_IDENTITY_EMPTY = "first=1000@avaya.com&second=2000@avaya.com&calling=&display=DisplayName";
    private Call call;
    private Participant firstParty, secondParty;
    private ClickToCall callMeCallYou;
    private ClusterAttributeDAO clusterAttributeDAO;
    private RequestProcessor requestProcessorImpl;
    private Logger logger;

    @Before
    public void setUp()
    {
        call = mock(Call.class);
        firstParty = mock(Participant.class);
        secondParty = mock(Participant.class);
        callMeCallYou = mock(ClickToCall.class);
        clusterAttributeDAO = (ClusterAttributeDAO) DMFactory.getInstance()
                .getDataMgr(ClusterAttributeDAO.class);
        logger = mock(Logger.class);
        requestProcessorImpl = new RequestProcessorImpl(callMeCallYou,
                clusterAttributeDAO, logger);

        when(firstParty.getHandle()).thenReturn(FIRST_PARTY_NO_DOMAIN);
        when(firstParty.getDomain()).thenReturn(DOMAIN);
        when(firstParty.getAddress()).thenReturn(FIRST_PARTY);
        when(secondParty.getHandle()).thenReturn(SECOND_PARTY_NO_DOMAIN);
        when(secondParty.getDomain()).thenReturn(DOMAIN);
        when(secondParty.getAddress()).thenReturn(SECOND_PARTY);
        when(call.getCallingParty()).thenReturn(firstParty);
        when(call.getCalledParty()).thenReturn(secondParty);
    }

    @Test
    public void processHttpPost_isValidBodyFormat() throws Exception
    {
        final String startBody = "first=";
        final String midBody = "&second=";
        final String callingId = "&calling=" + CALLING_ID_NO_DOMAIN;
        final String firstPartOfBody = startBody + firstParty.getHandle()
                + DOMAIN_DELIMITER_AT + firstParty.getDomain();
        final String secondPartOfBody = midBody + secondParty.getHandle()
                + DOMAIN_DELIMITER_AT + secondParty.getDomain();
        final String postBody = firstPartOfBody + secondPartOfBody + callingId;

        requestProcessorImpl.processHttpPost(postBody);
    }

    @Test
    public void getHandle_retrunValidHandleGivenDomain() throws Exception
    {
        assertEquals(firstParty.getHandle(), requestProcessorImpl.getHandle(FIRST_PARTY));
        assertEquals(secondParty.getHandle(), requestProcessorImpl.getHandle(SECOND_PARTY));
        assertEquals(CALLING_ID_NO_DOMAIN, requestProcessorImpl.getHandle(CALLING_ID));
    }

    @Test
    public void getHandle_retrunValidHandleNoDomain() throws Exception
    {
        assertEquals(firstParty.getHandle(), requestProcessorImpl.getHandle(FIRST_PARTY_NO_DOMAIN));
        assertEquals(secondParty.getHandle(), requestProcessorImpl.getHandle(SECOND_PARTY_NO_DOMAIN));
        assertEquals(CALLING_ID_NO_DOMAIN, requestProcessorImpl.getHandle(CALLING_ID_NO_DOMAIN));
    }

    @Test 
    public void getDomain_retrunValidDomainGivenDomain() throws Exception
    {
        assertEquals(firstParty.getDomain(), requestProcessorImpl.getDomain(FIRST_PARTY));
        assertEquals(secondParty.getDomain(), requestProcessorImpl.getDomain(SECOND_PARTY));
        assertEquals(DOMAIN, requestProcessorImpl.getDomain(CALLING_ID));
    }

    @Test
    public void getDomain_retrunDeafaultDomainNoDomainGiven() throws Exception
    {
        final String defaultDomain = clusterAttributeDAO.getClusterAttribute("SIPDefaultDomain");

        assertEquals(defaultDomain, requestProcessorImpl.getDomain(FIRST_PARTY_NO_DOMAIN));
        assertEquals(defaultDomain, requestProcessorImpl.getDomain(SECOND_PARTY_NO_DOMAIN));
        assertEquals(defaultDomain, requestProcessorImpl.getDomain(CALLING_ID_NO_DOMAIN));
    }

    @Test
    public void buildPhoneNumber_retrunValidAddressGivenDomain()
            throws Exception
    {
        assertEquals(firstParty.getAddress(), requestProcessorImpl.buildPhoneNumber(FIRST_PARTY));
        assertEquals(secondParty.getAddress(), requestProcessorImpl.buildPhoneNumber(SECOND_PARTY));
        assertEquals(CALLING_ID, requestProcessorImpl.buildPhoneNumber(CALLING_ID));
    }

    @Test
    public void buildPhoneNumber_retrunValidAddressNoDomain() throws Exception
    {
        final String defaultDomain = clusterAttributeDAO.getClusterAttribute("SIPDefaultDomain");
        final String buildFirstAPartyAddress = FIRST_PARTY_NO_DOMAIN + DOMAIN_DELIMITER_AT + defaultDomain;
        final String buildSecondAPartyAddress = SECOND_PARTY_NO_DOMAIN + DOMAIN_DELIMITER_AT + defaultDomain;
        final String buildCallingIdAddress = CALLING_ID_NO_DOMAIN + DOMAIN_DELIMITER_AT + defaultDomain;

        assertEquals(buildFirstAPartyAddress, requestProcessorImpl.buildPhoneNumber(FIRST_PARTY_NO_DOMAIN));
        assertEquals(buildSecondAPartyAddress, requestProcessorImpl.buildPhoneNumber(SECOND_PARTY_NO_DOMAIN));
        assertEquals(buildCallingIdAddress, requestProcessorImpl.buildPhoneNumber(CALLING_ID_NO_DOMAIN));
    }
    
    @Test(expected = IllegalArgumentException.class)
    public void processHttpPost_EmptyFirstParty_ExceptionThrown()
            throws Exception
    {
        requestProcessorImpl.processHttpPost(BODY_FIRST_PARTY_EMPTY);
    }
    
    @Test(expected = IllegalArgumentException.class)
    public void processHttpPost_EmptySecondParty_ExceptionThrown()
            throws Exception
    {
        requestProcessorImpl.processHttpPost(BODY_SECOND_PARTY_EMPTY);
    }
    
    @Test(expected = IllegalArgumentException.class)
    public void processHttpPost_EmptyCallingIndentity_ExceptionThrown()
            throws Exception
    {
        requestProcessorImpl.processHttpPost(BODY_CALLING_IDENTITY_EMPTY);
    }
}
