///////////////////////////////////////////////////////////////////////////////
//// MultiChanBroadcastCallListener.java
////Description:: MultiChanBroadcastCallListener is the call listener class which plays announcement after call is answered and
////when terminated logs the call  details.
////
//// Copyright 2013 Avaya Inc. All rights reserved.
//// Usage of this source is bound to the terms described
//// in http://www.avaya.com/devconnect
//// Avaya - Confidential & Proprietary. Use pursuant to your signed agreement or Avaya Policy.
/////////////////////////////////////////////////////////////////////////////////

package com.avaya.zephyr.services.multichanbroadcast.announcementcall;

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

@TheCallListener
public class MultiChanBroadcastCallListener extends CallListenerAbstract
{
    private static final String CALLINTERCEPTED_LOG = "callIntercepted invoked";
    private static final String CALLALERTING_LOG = "callAlerting invoked. AlertingParty=";
    private static final String CALLANSWERED_LOG_INVOKED =
            "callAnswered invoked. Attempting to play announcement to ";
    private static final String CALLTERMINATED_LOG_NO_CALL = "callTerminated invoked with null call";
    private static final String CALLTERMINATED_LOG_NO_CALLED_PARTY =
            "callTerminated invoked with null calledParty";
    private static final String CALLTERMINATED_LOG_INVOKED = "callTerminated invoked for call to ";
    private static final String CALLTERMINATED_LOG_DTMF_NOT_ACK =
            "callTerminated: DTMF NOT acknowledged for call to ";
    private static final String CALL_ATTRIBUTE_DIGITSCOLLECTED = "digitsCollected";
    private final Logger logger;
    private final MultiChanBroadcastMediaListener multiChanBroadcastMediaListener;

    public MultiChanBroadcastCallListener()
    {
        this.logger = Logger.getLogger(MultiChanBroadcastCallListener.class);
        this.multiChanBroadcastMediaListener = new MultiChanBroadcastMediaListener();
    }

    // JUnit constructor
    public MultiChanBroadcastCallListener(final Logger logger,
            final MultiChanBroadcastMediaListener multiChanBroadCastMediaListener)
    {
        this.logger = logger;
        this.multiChanBroadcastMediaListener = multiChanBroadCastMediaListener;
    }

    @Override
    public void callIntercepted(final Call call)
    {
        // This service should not receive a call.
        logger.error(CALLINTERCEPTED_LOG);
    }

    @Override
    public void callAlerting(final Participant alertingParty)
    {
        logger.info(CALLALERTING_LOG + alertingParty.getAddress());
    }

    // When the call is answered by the recipient Play an announcement.
    @Override
    public void callAnswered(final Call answeredCall)
    {
        logger.info(CALLANSWERED_LOG_INVOKED + answeredCall.getAnsweringParty().getAddress());
        multiChanBroadcastMediaListener.playAnnouncementAndCollectDigits(answeredCall);
    }

    // When the call is terminated log the Call details.
    @Override
    public void callTerminated(final Call terminatedCall, final CallTerminationCause cause)
    {
        if (terminatedCall == null)
        {
            logger.error(CALLTERMINATED_LOG_NO_CALL);
        }
        else
        {
            // Remove entries MultiChanBroadcastMediaListener's UUID/Call map
            multiChanBroadcastMediaListener.callTerminated(terminatedCall);

            final Participant calledPartyParticipant = terminatedCall.getCalledParty();
            final String calledPartyAddress;
            if (calledPartyParticipant == null)
            {
                calledPartyAddress = "null";
                logger.error(CALLTERMINATED_LOG_NO_CALLED_PARTY);
            }
            else
            {
                calledPartyAddress = calledPartyParticipant.getAddress();
            }

            final StringBuilder sbCallTerminatedLog = new StringBuilder();

            sbCallTerminatedLog.append(CALLTERMINATED_LOG_INVOKED).append(calledPartyAddress);

            if (cause != null)
            {
                sbCallTerminatedLog.append(" with cause ").append(cause.getValue());
            }
            else
            {
                sbCallTerminatedLog.append(" with cause null");
            }

            logger.info(sbCallTerminatedLog.toString());

            // Log that call was not acknowledged with DTMF
            if (terminatedCall.getAttribute(CALL_ATTRIBUTE_DIGITSCOLLECTED) == null ||
                    !(Boolean) terminatedCall
                            .getAttribute(CALL_ATTRIBUTE_DIGITSCOLLECTED))
            {
                final StringBuilder sbCallTerminatedLogDtmfNotAck = new StringBuilder();

                sbCallTerminatedLogDtmfNotAck.append(CALLTERMINATED_LOG_DTMF_NOT_ACK).append(
                        calledPartyAddress);

                logger.info(sbCallTerminatedLogDtmfNotAck.toString());
            }
        }
    }

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

    @Override
    public void callOriginated(final Call call)
    {
    }

    @Override
    public void mediaDetected(final Participant participant, final MediaType mediaDetected)
    {
    }

}
