/*****************************************************************************
 * © 2017 Avaya Inc. All rights reserved.
 ****************************************************************************/
package com.avaya.services.CallDeflection;

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

@TheCallListener
public final class CallDeflectionCallListener extends CallListenerAbstract
{
    private final CallDeflectionMediaOperations callDeflectionMediaOperation;
    private final Logger logger;

    public CallDeflectionCallListener()
    {
        this(new CallDeflectionMediaOperationsImpl(), Logger.getLogger(CallDeflectionCallListener.class));
    }

    CallDeflectionCallListener(final CallDeflectionMediaOperations callDeflectionMediaOperation, final Logger logger)
    {
        this.callDeflectionMediaOperation = callDeflectionMediaOperation;
        this.logger = logger;
    }

    @Override
    public void callIntercepted(final Call call)
    {
        if (logger.isFinerEnabled())
        {
            logger.finer("callIntercepted ENTER CallId=" + call.getId());
        }
        callDeflectionMediaOperation.executePromptAndCollectOperation(call, CallDeflectionMediaListener.PROMPT1);
        logger.finer("callIntercepted EXIT");
    }

    @Override
    public void callAnswered(final Call call)
    {
        logger.finer("callAnswered ENTER");
        if (logger.isFinestEnabled())
        {
            logger.finest("callAnswered for callId=" + call.getId());
            logger.finest("callAnswered activeParties = " + getActivePartiesString(call));
            logger.finest("callAnswered alertingParties = " + getAlertingPartiesString(call));
            if (call.getAnsweringParty() != null)
            {
                logger.finest("callAnswered answeringParty = " + call.getAnsweringParty().getAddress());
            }
        }
        logger.finer("callAnswered EXIT");
    }

    @Override
    public void callAlerting(final Participant alertingParty)
    {
        if (logger.isFinestEnabled())
        {
            logger.finest("callAlerting ENTER/EXIT " + alertingParty);
        }
    }

    @Override
    public void participantDropped(final Call call, final Participant droppedParticipant, final CallTerminationCause cause)
    {
        if (logger.isFinestEnabled())
        {
            logger.finest("participantDropped ENTER " + droppedParticipant);

            if (call.getActiveParties().isEmpty())
            {
                logger.finest("participantDropped EXIT - Last participant dropped.");
                return;
            }
        }

        logger.finer("participantDropped EXIT");
    }

    @Override
    public void callTerminated(final Call call, final CallTerminationCause cause)
    {
        logger.finer("callTerminated ENTER");
        if (logger.isFinestEnabled())
        {
            logger.finest("callTerminated for callId=" + call.getId() + " cause=" + cause);
        }
        logger.finer("callTerminated EXIT");
    }

    @Override
    public void addParticipantFailed(final Call call,
            final Participant participant, final CallTerminationCause cause)
    {

        if (logger.isFinestEnabled())
        {
            logger.finest(
                    "addParticipantFailed for callId=" + call.getId() + " participant=" + participant.getAddress() + " cause=" + cause);
            logger.finest("addParticipantFailed activeParties = " + getActivePartiesString(call));
            logger.finest("addParticipantFailed alertingParties = " + getAlertingPartiesString(call));
            if (call.getAnsweringParty() != null)
            {
                logger.finest("addParticipantFailed answeringParty = " +
                        call.getAnsweringParty().getAddress());
            }
        }
    }

    private String getActivePartiesString(final Call call)
    {
        final StringBuilder sb = new StringBuilder();
        for (final Participant participant : call.getActiveParties())
        {
            sb.append(participant.getAddress());
            sb.append(":");
            sb.append(participant.getState());
            sb.append(" ");
        }
        return sb.toString();
    }

    private String getAlertingPartiesString(final Call call)
    {
        final StringBuilder sb = new StringBuilder();
        for (final Participant participant : call.getAlertingParties())
        {
            sb.append(participant.getAddress());
            sb.append(" ");
        }
        return sb.toString();
    }
}
