/////////////////////////////////////////////////////////////////////////////
//Copyright Avaya Inc., All Rights Reserved
// THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AVAYA INC
// The copyright notice above does not evidence any
// actual or intended publication of such source code.
// Some third-party source code components may have been modified from
// their original versions by Avaya Inc.
// The modifications are Copyright Avaya Inc., All Rights Reserved.
//
//////////////////////////////////////////////////////////////////////////////
package com.avaya.services.whitelist.db;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

import java.util.ArrayList;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.NoResultException;

import javax.persistence.Query;

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

import com.avaya.collaboration.businessdata.api.NoAttributeFoundException;
import com.avaya.collaboration.businessdata.api.ServiceNotFoundException;
import com.avaya.collaboration.util.logger.Logger;
import com.avaya.services.whitelist.db.NamedQueriesList;
import com.avaya.services.whitelist.util.EntityManagerFactoryImpl;
import com.avaya.services.whitelist.util.IEntityManagerFactory;

public final class WhiteListDaoImplTest
{
    private WhiteListDao whiteListDao;
    private IEntityManagerFactory entityManagerFactory;
    private EntityManagerFactory factory;
    private EntityManager entityManager;
    private Logger logger;

    private Query query;
    private WhiteListEntry whiteListEntry;

    private final static String CALLING_NUMBER = "+15055551212";
    private final static String CALLED_NUMBER = "+17205551212";

    List<WhiteListEntry> createList = new ArrayList<WhiteListEntry>();
    List<WhiteListEntry> queryList = new ArrayList<WhiteListEntry>();
    List<WhiteListEntry> queryAllList = new ArrayList<WhiteListEntry>();
    List<WhiteListEntry> deleteList = new ArrayList<WhiteListEntry>();

    @Before
    public void setUp() throws NoAttributeFoundException, ServiceNotFoundException
    {
        entityManagerFactory = EntityManagerFactoryImpl.getInstance();
        factory = mock(EntityManagerFactory.class);
        entityManagerFactory.setFactory(factory);
        entityManager = mock(EntityManager.class);
        logger = mock(Logger.class);

        query = mock(Query.class);
        whiteListEntry = new WhiteListEntry();
        whiteListEntry.setCalledHandle(CALLED_NUMBER);
        whiteListEntry.setCallingHandle(CALLING_NUMBER);

        whiteListDao = new WhiteListDaoImpl(entityManager, logger);

        createList.add(whiteListEntry);
        queryList.add(whiteListEntry);
        queryAllList.add(whiteListEntry);
        deleteList.add(whiteListEntry);

        when(entityManagerFactory.initializeEntityManager()).thenReturn(entityManager);

        when(logger.isFinerEnabled()).thenReturn(true);
    }

    @Test
    public void isWhiteListedNumber_inDb()
    {
        when(entityManager.createNamedQuery(NamedQueriesList.FIND_WHITELIST_ENTRY))
                .thenReturn(query);
        when(query.setParameter(anyString(), anyString())).thenReturn(query);
        when(query.getSingleResult()).thenReturn(whiteListEntry);

        assertTrue(whiteListDao.isWhiteListedNumber(CALLING_NUMBER,
                CALLED_NUMBER));
    }

    @Test
    public void isWhiteListedNumber_notInDb()
    {
        when(entityManager.createNamedQuery(NamedQueriesList.FIND_WHITELIST_ENTRY))
                .thenReturn(query);
        when(query.setParameter(anyString(), anyString())).thenReturn(query);
        when(query.getSingleResult()).thenThrow(new NoResultException());

        assertFalse(whiteListDao.isWhiteListedNumber(CALLING_NUMBER,
                CALLED_NUMBER));
    }

    @Test
    public void isWhiteListedNumber_invalidQuery()
    {
        when(entityManager.createNamedQuery(NamedQueriesList.FIND_WHITELIST_ENTRY))
                .thenThrow(new IllegalArgumentException());
        assertFalse(whiteListDao.isWhiteListedNumber(CALLING_NUMBER,
                CALLED_NUMBER));
    }

    @Test
    public void createListEntries()
    {
        when(entityManager.createNamedQuery(NamedQueriesList.FIND_WHITELIST_ENTRIES)).thenReturn(query);
        when(query.getResultList()).thenReturn(createList);
        List<WhiteListEntry> list = whiteListDao.createWhiteListEntry(CALLING_NUMBER, CALLED_NUMBER);
        if (list != null)
        {
            assertFalse(list.isEmpty());
        }
    }

    @Test
    public void quertyOneEntry()
    {

        when(entityManager.createNamedQuery(NamedQueriesList.FIND_WHITELIST_ENTRY)).thenReturn(query);
        when(query.setParameter(anyString(), anyString())).thenReturn(query);
        when(query.getSingleResult()).thenReturn(whiteListEntry);
        assertFalse(whiteListDao.queryOneEntry(CALLING_NUMBER,
                CALLED_NUMBER).isEmpty());
    }

    @Test
    public void queryAllEntries()
    {
        when(entityManager.createNamedQuery(NamedQueriesList.FIND_WHITELIST_ENTRIES)).thenReturn(query);
        when(query.getResultList()).thenReturn(queryAllList);
        List<WhiteListEntry> list = whiteListDao.queryWhiteListEntries();
        assertFalse(list.isEmpty());
    }

    @Test
    public void deleteEntry()
    {

        when(entityManager.createNamedQuery(NamedQueriesList.FIND_WHITELIST_ENTRY)).thenReturn(query);
        when(query.setParameter(anyString(), anyString())).thenReturn(query);
        when(query.getSingleResult()).thenReturn(whiteListEntry);

        when(entityManager.createNamedQuery(NamedQueriesList.FIND_WHITELIST_ENTRIES)).thenReturn(query);
        when(query.getResultList()).thenReturn(deleteList);
        List<WhiteListEntry> list = whiteListDao.deleteWhiteListEntry(CALLING_NUMBER, CALLED_NUMBER);
        assertFalse(list.isEmpty());
    }
}
