///////////////////////////////////////////////////////////////////////////////
//// MultiChanBroadcastSmsSender.java
////
////Description: MultiChanBroadcastSmsSender class sends SMS to the list of recipients
//// 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.sms;

import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import com.avaya.collaboration.businessdata.api.ServiceData;
import com.avaya.collaboration.sms.SmsFactory;
import com.avaya.collaboration.sms.SmsRequest;
import com.avaya.collaboration.util.logger.Logger;

public class MultiChanBroadcastSmsSender
{
    private final Logger logger;
    private ServiceData serviceData = null;
    private HttpServletRequest httpRequest = null;
    private PrintWriter printWriter = null;

    public MultiChanBroadcastSmsSender(final ServiceData serviceData, final HttpServletRequest httpRequest,
            final PrintWriter printWriter)
    {
        this.serviceData = serviceData;
        this.httpRequest = httpRequest;
        this.printWriter = printWriter;
        logger = Logger.getLogger(MultiChanBroadcastSmsSender.class);
    }

    // Junit constructor
    public MultiChanBroadcastSmsSender(final ServiceData serviceData, final HttpServletRequest httpRequest,
            final PrintWriter printWriter, final Logger logger)
    {
        this.serviceData = serviceData;
        this.httpRequest = httpRequest;
        this.printWriter = printWriter;
        this.logger = logger;
    }

    static final String SMS_INFO_NOT_SENT_LOG = "Info: SMS will not be sent.";
    static final String SMS_ERROR_SEND_LOG = "Error: Error occured sending SMS.";

    public boolean sendSms()
    {
        boolean smsSent = false;

        final List<String> smsTos = getSmsTos();
        final String smsBody = getSmsBody();

        if (smsTos.isEmpty() || smsBody.isEmpty())
        {
            logHttpResponseInfo(SMS_INFO_NOT_SENT_LOG);
        }
        else
        {
            final String smsFrom = getSmsFrom();

            final SmsRequest smsRequest = SmsFactory.createSmsRequest(smsTos, smsBody);
            if (!smsFrom.isEmpty())
            {
                smsRequest.setSender(smsFrom);
            }

            // Create the listener and send the sms message
            final MultiChanBroadcastSmsListener multiChanBroadcastSmsListener =
                    new MultiChanBroadcastSmsListener(smsRequest);
            smsRequest.setListener(multiChanBroadcastSmsListener);

            try
            {
                smsRequest.send();
                logSendSuccess(smsRequest);
                smsSent = true;
            }
            catch (final Exception e)
            {
                logHttpResponseError(SMS_ERROR_SEND_LOG, e);
            }
        }

        return smsSent;
    }

    static final String SMS_PARAM_SMGR_FROM = "smsFrom";
    static final String SMS_ERROR_FROM_LOG = "Error: Error occured acquiring 'from' SMS number from SMGR.";
    static final String SMS_INFO_NO_FROM_LOG =
            "Info: No 'from' sms number specified in the MultiChanBroadcastService attribute page on SMGR.";

    private String getSmsFrom()
    {
        // Required - From SMGR GUI
        String smsFrom = "";

        try
        {
            smsFrom = serviceData.getServiceAttribute(SMS_PARAM_SMGR_FROM);
            if (smsFrom.isEmpty())
            {
                logHttpResponseInfo(SMS_INFO_NO_FROM_LOG);
            }
        }
        catch (final Exception e)
        {
            logHttpResponseError(SMS_ERROR_FROM_LOG, e);
        }

        return smsFrom;
    }

    static final String SMS_PARAM_HTTP_TO = "smsTo";
    static final String SMS_INFO_NO_TO_LOG = "Info: No SMS recipients specified in the HTTP request.";

    private List<String> getSmsTos()
    {
        // Required - From HTTP request
        final String[] smsTosFromHttpRequest = httpRequest.getParameterValues(SMS_PARAM_HTTP_TO);

        // Dynamic list to build collection of smsTos.
        // Will convert to String[] before returning.
        final List<String> smsTos = new ArrayList<String>();

        if (smsTosFromHttpRequest != null)
        {
            // Convert the smsTo addresses into a list of strings
            // and separate any sms addresses delimited by commas
            for (final String smsToCommaDelimited : smsTosFromHttpRequest)
            {
                for (final String smsTo : smsToCommaDelimited.split(","))
                {
                    if (smsTo.isEmpty())
                    {
                        continue;
                    }
                    smsTos.add(smsTo);
                }
            }
        }

        if (smsTos.isEmpty())
        {
            logHttpResponseInfo(SMS_INFO_NO_TO_LOG);
        }

        return smsTos;
    }

    static final String SMS_PARAM_HTTP_BODY = "smsBody";
    static final String SMS_INFO_NO_BODY_LOG = "Info: No SMS body specified in HTTP request.";

    private String getSmsBody()
    {
        // Required - From HTTP request - Only 1st with data used
        String smsBody = "";

        final String[] smsBodyFromHttpRequest = httpRequest.getParameterValues(SMS_PARAM_HTTP_BODY);

        if (smsBodyFromHttpRequest != null)
        {
            for (final String smsBodyEntry : smsBodyFromHttpRequest)
            {
                if (!smsBodyEntry.isEmpty())
                {
                    smsBody = smsBodyEntry;
                    break;
                }
            }
        }

        if (smsBody.isEmpty())
        {
            logHttpResponseInfo(SMS_INFO_NO_BODY_LOG);
        }

        return smsBody;
    }

    static final String SMS_INFO_SENT_LOG = "Info: SMS queued to be sent to ";

    private void logSendSuccess(final SmsRequest smsRequest)
    {
        // List of SMS addresses this request is queued to
        // be sent to
        final StringBuilder sbSmsAddresses = new StringBuilder();
        for (final String smsTo : smsRequest.getRecipients())
        {
            if (sbSmsAddresses.length() == 0)
            {
                sbSmsAddresses.append(smsTo);
            }
            else
            {
                sbSmsAddresses.append(", ").append(smsTo);
            }
        }

        logHttpResponseInfo(SMS_INFO_SENT_LOG + sbSmsAddresses.toString());
    }

    private void logHttpResponseInfo(final String log)
    {
        printWriter.println(log);
        logger.info(log);
    }

    private void logHttpResponseError(final String log, final Exception e)
    {
        printWriter.println(log);
        logger.error(log, e);
    }
}
