///////////////////////////////////////////////////////////////////////////////
//// DynamicTeamFormationEmailSender.java
////
//// 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.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.conference.scheduled.SchedConf;
import com.avaya.collaboration.email.EmailFactory;
import com.avaya.collaboration.email.EmailRequest;
import com.avaya.collaboration.util.logger.Logger;

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

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

    // Junit constructor
    public DynamicTeamFormationEmailSender(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 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.";
    public boolean sendEmail(final SchedConf conference)
    {
        boolean emailSent = false;

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

        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.getTo().addAll(emailTo);
            emailRequest.setSubject(emailSubject);
            emailRequest.setTextBody(emailBody);

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

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

        return emailSent;
    }

    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 DynamicTeamFormationService attribute page on SMGR.";
    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;
    }
    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 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 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 List<String> getEmailTo()
    {
        // Required - From HTTP request
        final List<String> emailToCommaDelimited = new ArrayList<String>();
        final List<String> emailTo = new ArrayList<String>();

        final String[] emailToFromHttpRequest = httpRequest.getParameterValues(EMAIL_PARAM_HTTP_TO);

        if (emailToFromHttpRequest != null)
        {
            for (final String emailToEntry : emailToFromHttpRequest)
            {
                if (!emailToEntry.isEmpty())
                {
                    emailToCommaDelimited.add(emailToEntry);
                }
            }
        }

        if (emailToCommaDelimited.isEmpty())
        {
            logHttpResponseInfo(EMAIL_INFO_NO_TO_LOG);
        }
        else
        {
            // Convert the emailTo addresses into a list of strings
            // and separate any email addresses delimited by commas
            for (final String emailToCommaDelimitedEntry : emailToCommaDelimited)
            {
                final String[] emailToArray = emailToCommaDelimitedEntry.split(",");
                for (final String emailAddress : emailToArray)
                {
                    emailTo.add(emailAddress);
                }
            }
        }

        return emailTo;
    }

    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 String getEmailSubject()
    {
        // Required - From HTTP request - Only 1st 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;
    }

        final String EMAIL_PARAM_HTTP_BODY = "emailBody";
        final String EMAIL_INFO_NO_BODY_LOG = "Info: No email body specified in HTTP request.";
    private String getEmailBody(final SchedConf conference)
    {
        // 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 emailBodyEntry : emailBodyFromHttpRequest)
            {
                if (!emailBodyEntry.isEmpty())
                {
                    emailBody = emailBodyEntry;
                    break;
                }
            }
        }

        if (emailBody.isEmpty())
        {
            logHttpResponseInfo(EMAIL_INFO_NO_BODY_LOG);
        }
        else
        {
            emailBody = emailBody + " conference URL:  " + conference.getUrl();
        }

        return emailBody;
    }

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

        logHttpResponseInfo(EMAIL_INFO_SENT_LOG + sbEmailAddresses.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);
    }
}
