///////////////////////////////////////////////////////////////////////////////
//// DynamicTeamFormationSmsSender.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.dynamicteamformation.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.conference.scheduled.SchedConf;
import com.avaya.collaboration.sms.SmsFactory;
import com.avaya.collaboration.sms.SmsRequest;
import com.avaya.collaboration.util.logger.Logger;

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

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

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

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

    public boolean sendSms(final SchedConf conference)
    {
        boolean smsSent = false;

        final List<String> smsTo = getSmsTo();
        final String smsBody = getSmsBody(conference);

        if (smsTo.isEmpty() || smsBody.isEmpty())
        {
            logHttpResponseInfo(SMS_INFO_NOT_SENT_LOG);
        }
        else
        {
            final SmsRequest smsRequest = SmsFactory.createSmsRequest(smsTo, smsBody);
            final String smsFrom = getSmsFrom();
            if (!smsFrom.isEmpty())
            {
                smsRequest.setSender(smsFrom);
            }

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

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

        return smsSent;
    }

    private static final String SMS_PARAM_SMGR_FROM = "smsFrom";
    private static final String SMS_ERROR_FROM_LOG = "Error: Error occured acquiring 'from' SMS number from SMGR.";
    private static final String SMS_INFO_NO_FROM_LOG =
            "Info: No 'from' sms number specified in the DynamicTeamFormationService 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;
    }

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

    private List<String> getSmsTo()
    {
        // Required - From HTTP request
        final List<String> smsToCommaDelimited = new ArrayList<String>();
        final List<String> smsTo = new ArrayList<String>();

        final String[] smsToFromHttpRequest = httpRequest.getParameterValues(SMS_PARAM_HTTP_TO);

        if (smsToFromHttpRequest != null)
        {
            for (final String smsToEntry : smsToFromHttpRequest)
            {
                if (!smsToEntry.isEmpty())
                {
                    smsToCommaDelimited.add(smsToEntry);
                }
            }
        }

        if (smsToCommaDelimited.isEmpty())
        {
            logHttpResponseInfo(SMS_INFO_NO_TO_LOG);
        }
        else
        {
            // Convert the smsTo addresses into a list of strings
            // and separate any sms addresses delimited by commas
            for (final String smsToCommaDelimitedEntry : smsToCommaDelimited)
            {
                final String[] smsToArray = smsToCommaDelimitedEntry.split(",");
                for (final String smsNumber : smsToArray)
                {
                    smsTo.add(smsNumber);
                }
            }
        }

        return smsTo;
    }

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

    private String getSmsBody(final SchedConf conference)
    {
        // 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);
        }
        else
        {
            smsBody = smsBody + " conference URL:  " + conference.getUrl();
        }

        return smsBody;
    }

    private 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);
    }
}
