/////////////////////////////////////////////////////////////////////////////
//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 java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.NoResultException;
import javax.persistence.Query;

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.util.EntityManagerFactoryImpl;

@Stateless
public class WhiteListDaoImpl implements WhiteListDao
{
    private EntityManager entityManager = null;

    private final Logger logger;

    public WhiteListDaoImpl()
    {
        this.logger = Logger.getLogger(WhiteListDaoImpl.class);
    }

    private void initializeEntityManager()
    {
        try
        {
            logger.finer("initializeEntityManager ENTER");
            entityManager = EntityManagerFactoryImpl.getInstance()
                    .initializeEntityManager();
        }
        catch (final NoAttributeFoundException | ServiceNotFoundException e)
        {
            entityManager = null;
            logger.error("initializeEntityManager exception=", e);
        }
        catch (final Exception e)
        {
            entityManager = null;
            logger.error("initializeEntityManager exception=", e);
            logger.logEvent("DB_ERROR_01");
        }
    }

    WhiteListDaoImpl(final EntityManager entityManager, final Logger logger)
    {
        this.entityManager = entityManager;
        this.logger = logger;
    }

    @Override
    public final boolean isWhiteListedNumber(final String callingNumber,
            final String calledNumber)
    {
        if (logger.isFinerEnabled())
        {
            final StringBuilder enterLog = new StringBuilder(
                    "isWhiteListedNumber ENTER entityManager=");
            enterLog.append(entityManager);
            enterLog.append(" caller number=");
            enterLog.append(callingNumber);
            enterLog.append(" called number=");
            enterLog.append(calledNumber);
            logger.finer(enterLog);
        }

        initializeEntityManager();

        try
        {
            if (entityManager != null)
            {
                final Query query = createNamedQuery(callingNumber,
                        calledNumber);
                final WhiteListEntry whiteListEntry = (WhiteListEntry) getSingleResult(query);
                logger.info("isWhiteListedNumber from named query whiteListEntry="
                        + whiteListEntry);
                return (whiteListEntry != null);
            }
            else
            {
                return false;
            }
        }
        catch (final Exception exception)
        {
            logger.error("isWhiteListedNumber exception=", exception);
            return false;
        }
        finally
        {
            if (entityManager != null)
            {
                entityManager.close();
                entityManager = null;
            }
        }
    }

    private Query createNamedQuery(final String callingNumber,
            final String calledNumber)
    {
        return entityManager
                .createNamedQuery(NamedQueriesList.FIND_WHITELIST_ENTRY)
                .setParameter("calledNumber", calledNumber)
                .setParameter("callingNumber", callingNumber);
    }

    private Query createNamedQueryForAllEntries()
    {
        return entityManager
                .createNamedQuery(NamedQueriesList.FIND_WHITELIST_ENTRIES);
    }

    private void queryWhiteListlogEnter()
    {
        if (logger.isFinerEnabled())
        {
            final StringBuilder enterLog = new StringBuilder(
                    "queryWhiteListEntries ENTER entityManager=");
            enterLog.append(entityManager);
            logger.finer(enterLog);
        }
    }

    private Object getSingleResult(final Query query)
    {
        try
        {
            return query.getSingleResult();
        }
        catch (final NoResultException noResultException)
        {
            return null;
        }
        catch (final Exception exception)
        {
            logger.error("getSingleResult exception=" + exception, exception);
            return null;
        }
    }

    @Override
    public List<WhiteListEntry> queryWhiteListEntries()
    {
        List<WhiteListEntry> allEntrieslist = new ArrayList<WhiteListEntry>();
        queryWhiteListlogEnter();
        initializeEntityManager();
        try
        {
            if (entityManager != null)
            {
                final Query query = createNamedQueryForAllEntries();
                allEntrieslist = query.getResultList();
                logger.fine("WhiteListDaoImpl :: queryWhiteListEntries from named query whiteListEntries=" +
                        allEntrieslist);
            }
            else
            {
                logger.error("WhiteListDaoImpl :: queryWhiteListEntries exception");
            }
        }
        catch (final Exception exception)
        {
            logger.error("WhiteListDaoImpl :: queryWhiteListEntries exception=", exception);
        }
        finally
        {
            if (entityManager != null)
            {
                entityManager.close();
                entityManager = null;
            }
        }
        return allEntrieslist;

    }

    @Override
    public List<WhiteListEntry> deleteWhiteListEntry(String callingParty, String calledParty)
    {
        List<WhiteListEntry> deleteEntriesList = new ArrayList<WhiteListEntry>();

        if (logger.isFinerEnabled())
        {
            final StringBuilder enterLog = new StringBuilder(
                    "DeleteWhiteListedNumber ENTER entityManager=");
            enterLog.append(entityManager);
            enterLog.append(" caller number=");
            enterLog.append(callingParty);
            enterLog.append(" called number=");
            enterLog.append(calledParty);
            logger.finer(enterLog);
        }
        initializeEntityManager();

        try
        {
            if (entityManager != null)
            {
                final Query query = createNamedQuery(callingParty,
                        calledParty);
                final WhiteListEntry whiteListEntry = (WhiteListEntry) getSingleResult(query);
                logger.fine("WhiteListDaoImpl :: deleteWhiteListNumber from named query whiteListEntry="
                        + whiteListEntry);
                if (whiteListEntry == null)
                {
                    deleteEntriesList=null;
                    return deleteEntriesList;
                }
                entityManager.remove(whiteListEntry);

                final Query listQuery = createNamedQueryForAllEntries();
                deleteEntriesList = listQuery.getResultList();
                logger.fine("WhiteListDaoImpl :: deleteWhiteListNumber from named query whiteListEntries=" +
                        deleteEntriesList);
            }
            else
            {
                logger.error("WhiteListDaoImpl :: deleteWhiteListNumber deleteEntry exception");
            }
        }
        catch (final Exception exception)
        {
            logger.error("WhiteListDaoImpl :: deleteWhiteListEntry exception=", exception);
        }
        finally
        {
            if (entityManager != null)
            {
                entityManager.close();
                entityManager = null;
            }
        }
        return deleteEntriesList;
    }

    @Override
    public List<WhiteListEntry> createWhiteListEntry(final String callingParty, final String calledParty)
    {
        List<WhiteListEntry> createEntriesList = null;
        if (logger.isFinerEnabled())
        {
            final StringBuilder enterLog = new StringBuilder(
                    "CreateWhiteListedNumber ENTER entityManager=");
            enterLog.append(entityManager);
            enterLog.append(" caller number=");
            enterLog.append(callingParty);
            enterLog.append(" called number=");
            enterLog.append(calledParty);
            logger.finer(enterLog);
        }

        initializeEntityManager();

        try
        {
            if (entityManager != null)
            {
                WhiteListEntry whiteListEntry = new WhiteListEntry();
                whiteListEntry.setCalledHandle(calledParty);
                whiteListEntry.setCallingHandle(callingParty);

                final Query findQuery = createNamedQuery(callingParty, calledParty);
                final WhiteListEntry checkEntry = (WhiteListEntry) getSingleResult(findQuery);
                logger.info("checkEntry is  " + checkEntry);
                
                if (checkEntry == null)
                {
                    entityManager.persist(whiteListEntry);

                    final Query query = createNamedQueryForAllEntries();
                    createEntriesList = query.getResultList();
                    logger.info("WhiteListDaoImpl :: createWhiteListEntry createEntry from named query whiteListEntries=" +
                            createEntriesList);
                }
                else
                {
                    final Query query = createNamedQueryForAllEntries();
                    createEntriesList = query.getResultList();
                    logger.info("WhiteListDaoImpl :: createWhiteListEntry createEntry from named query whiteListEntries=" +
                            createEntriesList);
                    return createEntriesList;
                }
            }
            else
            {
                logger.error("WhiteListDaoImpl :: createEntriesList exception");
            }
        }
        catch (final Exception exception)
        {
            logger.error("WhiteListDaoImpl :: createEntriesList exception=", exception);

        }
        finally
        {
            if (entityManager != null)
            {
                entityManager.close();
                entityManager = null;
            }
        }
        return createEntriesList;
    }

    @Override
    public List<WhiteListEntry> queryOneEntry(final String callingParty, final String calledParty)
    {
        List<WhiteListEntry> oneEntryList = new ArrayList<WhiteListEntry>();
        WhiteListEntry whiteListEntry = null;

        if (logger.isFinerEnabled())
        {
            final StringBuilder enterLog = new StringBuilder(
                    "isWhiteListedNumber ENTER entityManager=");
            enterLog.append(entityManager);
            enterLog.append(" caller number=");
            enterLog.append(callingParty);
            enterLog.append(" called number=");
            enterLog.append(calledParty);
            logger.finer(enterLog);
        }

        initializeEntityManager();

        try
        {
            if (entityManager != null)
            {
                final Query query = createNamedQuery(callingParty, calledParty);
                whiteListEntry = (WhiteListEntry) getSingleResult(query);
                logger.fine("WhiteListDaoImpl :: queryOneEntry from named query whiteListEntry=" + whiteListEntry);

                oneEntryList.add(whiteListEntry); // Implemented using List, for UI purposes.
                logger.fine("WhiteListDaoImpl : One entry list" + oneEntryList);
                
                if(whiteListEntry == null)
                {
                    oneEntryList = null;
                }

            }
            else
            {
                return null;
            }
        }
        catch (final Exception exception)
        {
            logger.error("WhiteListDaoImpl : queryOneEntry exception=", exception);
        }
        finally
        {
            if (entityManager != null)
            {
                entityManager.close();
                entityManager = null;
            }
        }
        return oneEntryList;
    }

    @Override
    public List<WhiteListEntry> queryEntryByCalledHandle(final String calledParty)
    {
        List<WhiteListEntry> entryListByCalledParty = new ArrayList<WhiteListEntry>();
        List<WhiteListEntry> allEntriesList = null;
        
        Iterator<WhiteListEntry> iter = null;

        if (logger.isFinerEnabled())
        {
            final StringBuilder enterLog = new StringBuilder(
                    "queryEntryByCalledHandle ENTER entityManager=");
            enterLog.append(entityManager);
            enterLog.append(" called number=");
            enterLog.append(calledParty);
            logger.finer(enterLog);
        }

        initializeEntityManager();

        try
        {
            if (entityManager != null)
            {
                final Query query = createNamedQueryForAllEntries();
                allEntriesList = query.getResultList();
                logger.fine("WhiteListDaoImpl :: queryWhiteListEntries All from named query whiteListEntries=" +
                        allEntriesList);
                
                if(allEntriesList!=null)
                {
                    iter = allEntriesList.iterator();
                }
                
                if(iter !=null)
                {
                while (iter.hasNext())
                {
                    WhiteListEntry whiteListEntry = iter.next();
                    if (whiteListEntry.getCalledHandle().equals(calledParty))
                    {   
                        entryListByCalledParty.add(whiteListEntry);
                    } 
                }
                
                }
                
                if(entryListByCalledParty.isEmpty())
                {
                    logger.info("entryListByCalledParty status is : "+ entryListByCalledParty);
                    return null;
                }
                
            }
            else
            {
                return null;
            }
        }
        catch (final Exception exception)
        {
            logger.error("WhiteListDaoImpl : queryOneEntry exception=", exception);
        }
        finally
        {
            if (entityManager != null)
            {
                entityManager.close();
                entityManager = null;
            }
        }
        return entryListByCalledParty;
    }

}
