///////////////////////////////////////////////////////////////////////////////
//// MultiChanBroadcastEmailSender.java
////Description: MultiChanBroadcastEmailSender class is responsible for sending email's 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.email;

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.email.EmailFactory;
import com.avaya.collaboration.email.EmailRequest;
import com.avaya.collaboration.util.logger.Logger;

public class MultiChanBroadcastEmailSender
{
    private final Logger logger;
    private ServiceData serviceData = null;
    private HttpServletRequest httpRequest = null;
    private PrintWriter printWriter = null;
    private static final String EMAIL_INFO_NOT_SENT_LOG = "Info: Email will not be sent.";
    private static final String EMAIL_ERROR_SEND_LOG = "Error: Error occured sending email.";
    private static final String EMAIL_INFO_USE_EC_FROM_LOG =
        "Will attempt to use the email connector's 'default sender' attribute for the 'from' address.";
    private static final String EMAIL_PARAM_SMGR_FROM = "emailFrom";
    private static final String EMAIL_ERROR_FROM_LOG =
        "Error: Error occured acquiring 'from' email address from SMGR.";
    private static final String EMAIL_INFO_NO_FROM_LOG =
        "Info: No 'from' email address specified in the MultiChanBroadcastService attribute page on SMGR.";
    private static final String EMAIL_PARAM_SMGR_REPLYTO = "emailReplyTo";
    private static final String EMAIL_ERROR_REPLYTO_LOG =
        "Error: Error occured acquiring 'replyTo' email address from SMGR.";
    private static final String EMAIL_PARAM_HTTP_TO = "emailTo";
    private static final String EMAIL_INFO_NO_TO_LOG = "Info: No email recipients specified in the HTTP request.";
    private static final String EMAIL_PARAM_HTTP_SUBJECT = "emailSubject";
    private static final String EMAIL_INFO_NO_SUBJECT_LOG = "Info: No email subject specified in HTTP request.";
    private static final String EMAIL_PARAM_HTTP_BODY = "emailBody";
    private static final String EMAIL_INFO_NO_BODY_LOG = "Info: No email body specified in HTTP request.";
    private static final String EMAIL_INFO_SENT_LOG = "Info: Email queued to be sent to ";

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

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

    // This Method sends email to the list of recipients with subject and email
    // body
    public boolean sendEmail()
    {
        boolean emailSent = false;

        final List<String> emailTo = getEmailTos();
        final String emailSubject = getEmailSubject();
        final String emailBody = getEmailBody();

        if (emailTo.isEmpty() || emailSubject.isEmpty() || emailBody.isEmpty())
        {
            logHttpResponseInfo(EMAIL_INFO_NOT_SENT_LOG);
        }
        else
        {
            final String emailFrom = getEmailFrom();
            final String emailReplyTo = getEmailReplyTo();

            if (emailFrom.isEmpty())
            {
                logHttpResponseInfo(EMAIL_INFO_USE_EC_FROM_LOG);
            }

            final EmailRequest emailRequest = EmailFactory.createEmailRequest();
            emailRequest.setFrom(emailFrom);
            emailRequest.setReplyTo(emailReplyTo);
            emailRequest.getBcc().addAll(emailTo);
            emailRequest.setSubject(emailSubject);
            emailRequest.setTextBody(emailBody);

            // Create the listener and send the email message
            final MultiChanBroadcastEmailListener multiChanBroadcastEmailListener =
                    new MultiChanBroadcastEmailListener(emailRequest);
            emailRequest.setListener(multiChanBroadcastEmailListener);

            try
            {
                emailRequest.send();
                logSendSuccess(emailRequest);
                emailSent = true;
            }
            catch (final Exception e)
            {
                logHttpResponseError(EMAIL_ERROR_SEND_LOG, e);
            }
        }

        return emailSent;
    }

    // Used in the 'From' header of the broadcast email.
    private String getEmailFrom()
    {
        // Required - From SMGR GUI
        String emailFrom = "";

        try
        {
            emailFrom = serviceData.getServiceAttribute(EMAIL_PARAM_SMGR_FROM);
            if (emailFrom.isEmpty())
            {
                logHttpResponseInfo(EMAIL_INFO_NO_FROM_LOG);
            }
        }
        catch (final Exception e)
        {
            logHttpResponseError(EMAIL_ERROR_FROM_LOG, e);
        }

        return emailFrom;
    }

    // Used for replies to the broadcast email.
    private String getEmailReplyTo()
    {
        // NOT required - From SMGR GUI
        String emailReplyTo = "";

        try
        {
            emailReplyTo = serviceData.getServiceAttribute(EMAIL_PARAM_SMGR_REPLYTO);
        }
        catch (final Exception e)
        {
            logHttpResponseError(EMAIL_ERROR_REPLYTO_LOG, e);
        }

        return emailReplyTo;
    }

    private List<String> getEmailTos()
    {
        // Required - From HTTP request - Added as BCC to email message
        final String[] emailTosFromHttpRequest = httpRequest.getParameterValues(EMAIL_PARAM_HTTP_TO);

        // Dynamic list to build collection of emailTos.
        final List<String> emailTos = new ArrayList<String>();

        // Get the list of Email 'To' values from HTTP request

        // Convert the emailTo addresses into a list of strings
        // and separate any email addresses delimited by commas
        if (emailTosFromHttpRequest != null)
        {
            for (final String emailTosCommaDelimited : emailTosFromHttpRequest)
            {
                // Separate entries if delimited with a comma
                for (final String emailTo : emailTosCommaDelimited.split(","))
                {
                    if (emailTo.isEmpty())
                    {
                        continue;
                    }
                    emailTos.add(emailTo);
                }
            }
        }

        if (emailTos.isEmpty())
        {
            logHttpResponseInfo(EMAIL_INFO_NO_TO_LOG);
        }

        return emailTos;
    }

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

        final String[] emailSubjectFromHttpRequest = httpRequest.getParameterValues(EMAIL_PARAM_HTTP_SUBJECT);

        if (emailSubjectFromHttpRequest != null)
        {
            for (final String emailSubjectEntry : emailSubjectFromHttpRequest)
            {
                if (!emailSubjectEntry.isEmpty())
                {
                    emailSubject = emailSubjectEntry;
                    break;
                }
            }
        }

        if (emailSubject.isEmpty())
        {
            logHttpResponseInfo(EMAIL_INFO_NO_SUBJECT_LOG);
        }

        return emailSubject;
    }

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

        final String[] emailBodyFromHttpRequest = httpRequest.getParameterValues(EMAIL_PARAM_HTTP_BODY);

        if (emailBodyFromHttpRequest != null)
        {
            for (final String emailToEntry : emailBodyFromHttpRequest)
            {
                if (!emailToEntry.isEmpty())
                {
                    emailBody = emailToEntry;
                    break;
                }
            }
        }

        if (emailBody.isEmpty())
        {
            logHttpResponseInfo(EMAIL_INFO_NO_BODY_LOG);
        }

        return emailBody;
    }

    private void logSendSuccess(final EmailRequest emailRequest)
    {
        // List of email addresses this request is queued to
        // be sent to
        final StringBuilder sbEmailAddressesInBcc = new StringBuilder();
        for (final String emailTo : emailRequest.getBcc())
        {
            if (sbEmailAddressesInBcc.length() == 0)
            {
                sbEmailAddressesInBcc.append(emailTo);
            }
            else
            {
                sbEmailAddressesInBcc.append(", ").append(emailTo);
            }
        }

        logHttpResponseInfo(EMAIL_INFO_SENT_LOG + sbEmailAddressesInBcc.toString());
    }

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

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