/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 *  contributor license agreements.  The ASF licenses this file to You
 * under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.  For additional information regarding
 * copyright in this work, please see the NOTICE file in the top level
 * directory of this distribution.
 */

package org.apache.roller.weblogger.util;

import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.ResourceBundle;
import java.util.Set;
import java.util.TreeSet;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.SendFailedException;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.Address;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.roller.weblogger.WebloggerException;
import org.apache.roller.weblogger.business.MailProvider;
import org.apache.roller.weblogger.business.WebloggerFactory;
import org.apache.roller.weblogger.business.WeblogManager;
import org.apache.roller.weblogger.business.startup.WebloggerStartup;
import org.apache.roller.weblogger.config.WebloggerRuntimeConfig;
import org.apache.roller.weblogger.pojos.User;
import org.apache.roller.weblogger.pojos.WeblogEntry;
import org.apache.roller.weblogger.pojos.Weblog;
import org.apache.roller.weblogger.pojos.WeblogEntryComment;
import org.apache.roller.weblogger.pojos.WeblogPermission;
import org.apache.roller.weblogger.util.RollerMessages.RollerMessage;


/**
 * A utility class for helping with sending email. 
 */
public class MailUtil {
    
    private static Log log = LogFactory.getLog(MailUtil.class);
    
    private static final String EMAIL_ADDR_REGEXP = "^.*@.*[.].{2,}$";
    
    
    /**
     * Ideally mail senders should call this first to avoid errors that occur 
     * when mail is not properly configured. We'll complain about that at 
     * startup, no need to complain on every attempt to send.
     */
    public static boolean isMailConfigured() {
        return WebloggerStartup.getMailProvider() != null; 
    }
    
    /**
     * Send an email notice that a new pending entry has been submitted.
     */
    public static void sendPendingEntryNotice(WeblogEntry entry) throws WebloggerException {
        
        Session mailSession = WebloggerStartup.getMailProvider() != null
                ? WebloggerStartup.getMailProvider().getSession() : null;

        if (mailSession == null) {
            throw new WebloggerException("Couldn't get mail Session");
        }
        
        try {
            WeblogManager wmgr = WebloggerFactory.getWeblogger().getWeblogManager();
            
            String userName = entry.getCreator().getUserName();
            String from = entry.getCreator().getEmailAddress();
            String cc[] = new String[] {from};
            String bcc[] = new String[0];
            String to[];
            String subject;
            String content;
            
            // list of enabled website authors and admins
            List<String> reviewers = new ArrayList<String>();
            List<User> websiteUsers = wmgr.getWeblogUsers(entry.getWebsite(), true);
            
            // build list of reviewers (website users with author permission)
            for (User websiteUser : websiteUsers) {
                if (entry.getWebsite().hasUserPermission(
                        websiteUser, WeblogPermission.POST)
                        && websiteUser.getEmailAddress() != null) {
                    reviewers.add(websiteUser.getEmailAddress());
                }
            }

            to = (String[])reviewers.toArray(new String[reviewers.size()]);
            
            // Figure URL to entry edit page
            String editURL = WebloggerFactory.getWeblogger().getUrlStrategy().getEntryEditURL(entry.getWebsite().getHandle(), entry.getId(), true);
            
            ResourceBundle resources = ResourceBundle.getBundle(
                    "ApplicationResources", entry.getWebsite().getLocaleInstance());
            StringBuilder sb = new StringBuilder();
            sb.append(
                    MessageFormat.format(
                    resources.getString("weblogEntry.pendingEntrySubject"),
                    new Object[] {
                entry.getWebsite().getName(),
                entry.getWebsite().getHandle()
            }));
            subject = sb.toString();
            sb = new StringBuilder();
            sb.append(
                    MessageFormat.format(
                    resources.getString("weblogEntry.pendingEntryContent"),
                    new Object[] { userName, userName, editURL })
                    );
            content = sb.toString();
            MailUtil.sendTextMessage(
                    from, to, cc, bcc, subject, content);
        } catch (MessagingException e) {
            log.error("ERROR: Problem sending pending entry notification email.");
        }
    }
    
    
    /**
     * Send a weblog invitation email.
     */
    public static void sendWeblogInvitation(Weblog website, User user)
            throws WebloggerException {
        
        Session mailSession = WebloggerStartup.getMailProvider() != null
                ? WebloggerStartup.getMailProvider().getSession() : null;

        if(mailSession == null) {
            throw new WebloggerException("ERROR: Notification email(s) not sent, "
                    + "Roller's mail session not properly configured");
        }
        
        try {
            String from = website.getEmailAddress();
            String cc[] = new String[] {from};
            String bcc[] = new String[0];
            String to[] = new String[] {user.getEmailAddress()};
            String subject;
            String content;
            
            // Figure URL to entry edit page
            String rootURL = WebloggerRuntimeConfig.getAbsoluteContextURL();
            String url = rootURL + "/roller-ui/menu.rol";
            
            ResourceBundle resources = ResourceBundle.getBundle(
                    "ApplicationResources",
                    website.getLocaleInstance());
            StringBuilder sb = new StringBuilder();
            sb.append(MessageFormat.format(
                    resources.getString("inviteMember.notificationSubject"),
                    new Object[] {
                website.getName(),
                website.getHandle()})
                );
            subject = sb.toString();
            sb = new StringBuilder();
            sb.append(MessageFormat.format(
                    resources.getString("inviteMember.notificationContent"),
                    new Object[] {
                website.getName(),
                website.getHandle(),
                user.getUserName(),
                url
            }));
            content = sb.toString();
            MailUtil.sendTextMessage(
                    from, to, cc, bcc, subject, content);
        } catch (MessagingException e) {
            throw new WebloggerException("ERROR: Notification email(s) not sent, "
                    + "due to Roller configuration or mail server problem.", e);
        }
    }
    
    
    /**
     * Send a weblog invitation email.
     */
    public static void sendUserActivationEmail(User user)
            throws WebloggerException {
        
        Session mailSession = WebloggerStartup.getMailProvider() != null
                ? WebloggerStartup.getMailProvider().getSession() : null;

        if(mailSession == null) {
            throw new WebloggerException("ERROR: Notification email(s) not sent, "
                    + "Roller's mail session not properly configured");
        }
        
        try {
            ResourceBundle resources = ResourceBundle.getBundle(
                    "ApplicationResources", I18nUtils.toLocale(user.getLocale()));
            
            String from = WebloggerRuntimeConfig.getProperty(
                    "user.account.activation.mail.from");
            
            String cc[] = new String[0];
            String bcc[] = new String[0];
            String to[] = new String[] { user.getEmailAddress() };
            String subject = resources.getString(
                    "user.account.activation.mail.subject");
            String content;
            
            String rootURL = WebloggerRuntimeConfig.getAbsoluteContextURL();
            
            StringBuilder sb = new StringBuilder();
            
            // activationURL=
            String activationURL = rootURL
                    + "/roller-ui/register!activate.rol?activationCode="
                    + user.getActivationCode();
            sb.append(MessageFormat.format(
                    resources.getString("user.account.activation.mail.content"),
                    new Object[] { user.getFullName(), user.getUserName(),
                    activationURL }));
            content = sb.toString();
            
            sendHTMLMessage(from, to, cc, bcc, subject, content);
        } catch (MessagingException e) {
            throw new WebloggerException("ERROR: Problem sending activation email.", e);
        }
    }
    
    
    /**
     * Send email notification of new or newly approved comment.
     *
     * @param commentObject      The new comment
     * @param messages           Messages to be included in e-mail (or null). 
     *                           Errors will be assumed to be "validation errors" 
     *                           and messages will be assumed to be "from the system"
     */
    public static void sendEmailNotification(WeblogEntryComment commentObject,
                                             RollerMessages messages, 
                                             I18nMessages resources,
                                             boolean notifySubscribers) 
            throws MailingException {

        // TODO: Factor out email notification from moderate message to owner.

        WeblogEntry entry = commentObject.getWeblogEntry();
        Weblog weblog = entry.getWebsite();
        User user = entry.getCreator();
        
        // Only send email if email notification is enabled, or a pending message that needs moderation.
        if (!commentObject.getPending()) {
            boolean notify = WebloggerRuntimeConfig.getBooleanProperty("users.comments.emailnotify");
            if (!notify) {
                // notifications disabled, just bail
                return;
            } else {
                log.debug("Comment notification enabled ... preparing email");
            }
        } else {
            log.debug("Pending comment...sending moderation email to blog owner");
        }

        // build list of email addresses to send notification to
        Set<String> subscribers = new TreeSet<String>();
        
        // If we are to notify subscribers, then...
        if (commentObject.getApproved() && notifySubscribers) {
            log.debug("Sending notification email to all subscribers");

            // Get all the subscribers to this comment thread
            List<WeblogEntryComment> comments = entry.getComments(true, true);
            for (WeblogEntryComment comment : comments) {
                if (!StringUtils.isEmpty(comment.getEmail())) {
                    // if user has commented twice, count the most recent notify setting
                    // also, don't send a routing email to the person who made the comment.
                    if (comment.getNotify() && !comment.getEmail().equals(commentObject.getEmail())) {
                        // only add those with valid email
                        if (comment.getEmail().matches(EMAIL_ADDR_REGEXP)) {
                            log.info("Add to subscribers list : " + comment.getEmail());
                            subscribers.add(comment.getEmail());
                        }
                    } else {
                        // remove user who doesn't want to be notified
                        log.info("Remove from subscribers list : " + comment.getEmail());
                        subscribers.remove(comment.getEmail());
                    }
                }
            }
        } else {
            log.debug("Sending notification email only to weblog owner");
        }

        //------------------------------------------
        // Form the messages to be sent -
        // The owner email gets the subscriber message with additional header and footer info added
        
        // Determine with mime type to use for e-mail
        StringBuilder msg = new StringBuilder();
        StringBuilder ownermsg = new StringBuilder();
        boolean isPlainText = !WebloggerRuntimeConfig.getBooleanProperty("users.comments.htmlenabled");
        
        // first the common stub message for the owner and commenters (if applicable)
        if (!isPlainText) {
            msg.append("<html><body style=\"background: white; ");
            msg.append(" color: black; font-size: 12px\">");
        }
        
        if (!StringUtils.isEmpty(commentObject.getName())) {
            msg.append(commentObject.getName() + " "
                    + resources.getString("email.comment.wrote")+": ");
        } else {
            msg.append(resources.getString("email.comment.anonymous")+": ");
        }
        
        msg.append((isPlainText) ? "\n\n" : "<br /><br />");

        // Don't escape the content if email will be sent as plain text
        msg.append((isPlainText) ? commentObject.getContent()
        : Utilities.transformToHTMLSubset(Utilities.escapeHTML(commentObject.getContent())));
        
        msg.append((isPlainText) ? "\n\n----\n"
                : "<br /><br /><hr /><span style=\"font-size: 11px\">");
        msg.append(resources.getString("email.comment.respond") + ": ");
        msg.append((isPlainText) ? "\n" : "<br />");
        
        // Build link back to comment
        String commentURL = WebloggerFactory.getWeblogger()
            .getUrlStrategy().getWeblogCommentsURL(weblog, null, entry.getAnchor(), true);
        
        if (isPlainText) {
            msg.append(commentURL);
        } else {
            msg.append("<a href=\""+commentURL+"\">"+commentURL+"</a></span>");
        }
        
        // next the additional information that is sent to the blog owner
        // Owner gets an email if it's pending and/or he's turned on notifications
        if (commentObject.getPending() || weblog.getEmailComments()) {
            // First, list any messages from the system that were passed in:
            if (messages.getMessageCount() > 0) {
                ownermsg.append((isPlainText) ? "" : "<p>");
                ownermsg.append(resources.getString("commentServlet.email.thereAreSystemMessages"));
                ownermsg.append((isPlainText) ? "\n\n" : "</p>");
                ownermsg.append((isPlainText) ? "" : "<ul>");
            }
            for (Iterator it = messages.getMessages(); it.hasNext();) {
                RollerMessage rollerMessage = (RollerMessage)it.next();
                ownermsg.append((isPlainText) ? "" : "<li>");
                ownermsg.append(MessageFormat.format(resources.getString(
                    rollerMessage.getKey()), (Object[])rollerMessage.getArgs()) );
                ownermsg.append((isPlainText) ? "\n\n" : "</li>");
            }
            if (messages.getMessageCount() > 0) {
                ownermsg.append((isPlainText) ? "\n\n" : "</ul>");
            }

            // Next, list any validation error messages that were passed in:
            if (messages.getErrorCount() > 0) {
                ownermsg.append((isPlainText) ? "" : "<p>");
                ownermsg.append(resources.getString("commentServlet.email.thereAreErrorMessages"));
                ownermsg.append((isPlainText) ? "\n\n" : "</p>");
                ownermsg.append((isPlainText) ? "" : "<ul>");
            }
            for (Iterator it = messages.getErrors(); it.hasNext();) {
                RollerMessage rollerMessage = (RollerMessage)it.next();
                ownermsg.append((isPlainText) ? "" : "<li>");
                ownermsg.append(MessageFormat.format(resources.getString(
                    rollerMessage.getKey()), (Object[])rollerMessage.getArgs()) );
                ownermsg.append((isPlainText) ? "\n\n" : "</li>");
            }
            if (messages.getErrorCount() > 0) {
                ownermsg.append((isPlainText) ? "\n\n" : "</ul>");
            }

            ownermsg.append(msg);

            ownermsg.append((isPlainText) ? "\n\n----\n" :
                "<br /><br /><hr /><span style=\"font-size: 11px\">");

            // commenter email address: allow blog owner to reply via email instead of blog comment
            if (!StringUtils.isBlank(commentObject.getEmail())) {
                ownermsg.append(resources.getString("email.comment.commenter.email") + ": " + commentObject.getEmail());
                ownermsg.append((isPlainText) ? "\n\n" : "<br/><br/>");
            }
            // add link to weblog edit page so user can login to manage comments
            ownermsg.append(resources.getString("email.comment.management.link") + ": ");
            ownermsg.append((isPlainText) ? "\n" : "<br/>");

            Map<String, String> parameters = new HashMap<String, String>();
            parameters.put("bean.entryId", entry.getId());
            String deleteURL = WebloggerFactory.getWeblogger().getUrlStrategy().getActionURL(
                    "comments", "/roller-ui/authoring", weblog.getHandle(), parameters, true);

            if (isPlainText) {
                ownermsg.append(deleteURL);
            } else {
                ownermsg.append(
                        "<a href=\"" + deleteURL + "\">" + deleteURL + "</a></span>");
                msg.append("</Body></html>");
                ownermsg.append("</Body></html>");
            }
        }

        // determine email subject
        String subject;
        if (commentObject.getPending()) {
            subject = resources.getString("email.comment.moderate.title") + ": ";
        } else {
            if ((subscribers.size() > 1) ||
                    (StringUtils.equals(commentObject.getEmail(), user.getEmailAddress()))) {
                subject= "RE: "+resources.getString("email.comment.title")+": ";
            } else {
                subject = resources.getString("email.comment.title") + ": ";
            }
        }
        subject += entry.getTitle();
        
        // send message to email recipients
        try {
            // use either the weblog configured from address or the site configured from address
            String from = weblog.getEmailAddress();
            if(StringUtils.isEmpty(from)) {
                from = user.getEmailAddress();
            }

            boolean isHtml = !isPlainText;
            
            if (commentObject.getPending() || weblog.getEmailComments()) {
                if(isHtml) {
                    sendHTMLMessage(
                            from,
                            new String[]{user.getEmailAddress()},
                            null,
                            null,
                            subject,
                            ownermsg.toString());
                } else {
                    sendTextMessage(
                            from,
                            new String[]{user.getEmailAddress()},
                            null,
                            null,
                            subject,
                            ownermsg.toString());
                }
            }

            // now send to subscribers
            if (notifySubscribers && subscribers.size() > 0) {
                // Form array of commenter addrs
                String[] commenterAddrs = subscribers.toArray(new String[subscribers.size()]);

                if (isHtml) {
                    sendHTMLMessage(
                            from, 
                            null,
                            null,
                            commenterAddrs,
                            subject, 
                            msg.toString());
                } else {
                    sendTextMessage(
                            from, 
                            null,
                            null,
                            commenterAddrs,
                            subject, 
                            msg.toString());
                }
            }
        } catch (Exception e) {
            log.warn("Exception sending comment notification mail", e);
            // This will log the stack trace if debug is enabled
            if (log.isDebugEnabled()) {
                log.debug(e);
            }
        }
        
        log.debug("Done sending email message");
    }
    

    public static void sendEmailApprovalNotifications(List<WeblogEntryComment> comments,
                                               I18nMessages resources) 
            throws MailingException {
        
        RollerMessages messages = new RollerMessages();
        for (WeblogEntryComment comment : comments) {

            // Send email notifications because a new comment has been approved
            sendEmailNotification(comment, messages, resources, true);

            // Send approval notification to author of approved comment
            sendEmailApprovalNotification(comment, resources);
        }
    }
    
    
    /**
     * Send message to author of approved comment
     */
    public static void sendEmailApprovalNotification(WeblogEntryComment cd, I18nMessages resources)
            throws MailingException {
        
        WeblogEntry entry = cd.getWeblogEntry();
        Weblog weblog = entry.getWebsite();
        User user = entry.getCreator();
        
        // use either the weblog configured from address or the site configured from address
        String from = weblog.getEmailAddress();
        if(StringUtils.isEmpty(from)) {
            from = user.getEmailAddress();
        }
        
        // form the message to be sent
        String subject = resources.getString("email.comment.commentApproved");
        
        StringBuilder msg = new StringBuilder();
        msg.append(resources.getString("email.comment.commentApproved"));
        msg.append("\n\n");
        msg.append(WebloggerFactory.getWeblogger().getUrlStrategy()
            .getWeblogCommentsURL(weblog, null, entry.getAnchor(), true));
        
        // send message to author of approved comment
        try {
            sendTextMessage(from, new String[] {cd.getEmail()}, null, null, subject, msg.toString());
        } catch (Exception e) {
            log.warn("Exception sending comment mail: " + e.getMessage());
            // This will log the stack trace if debug is enabled
            if (log.isDebugEnabled()) {
                log.debug(e);
            }
        }
        
        log.debug("Done sending email message");
    }
    
    
    // agangolli: Incorporated suggested changes from Ken Blackler.
    
    /**
     * This method is used to send a Message with a pre-defined
     * mime-type.
     *
     * @param from e-mail address of sender
     * @param to e-mail address(es) of recipients
     * @param subject subject of e-mail
     * @param content the body of the e-mail
     * @param mimeType type of message, i.e. text/plain or text/html
     * @throws MessagingException the exception to indicate failure
     */
    public static void sendMessage(String from, String[] to, String[] cc, String[] bcc, String subject,
            String content, String mimeType) throws MessagingException {
        
        MailProvider mailProvider = WebloggerStartup.getMailProvider();
        if (mailProvider == null) {
            return;
        }
        
        Session session = mailProvider.getSession();
        MimeMessage message = new MimeMessage(session);
        
        // n.b. any default from address is expected to be determined by caller.
        if (! StringUtils.isEmpty(from)) {
            InternetAddress sentFrom = new InternetAddress(from);
            message.setFrom(sentFrom);
            if (log.isDebugEnabled()) {
                log.debug("e-mail from: " + sentFrom);
            }
        }
        
        if (to!=null) {
            InternetAddress[] sendTo = new InternetAddress[to.length];
            
            for (int i = 0; i < to.length; i++) {
                sendTo[i] = new InternetAddress(to[i]);
                if (log.isDebugEnabled()) {
                    log.debug("sending e-mail to: " + to[i]);
                }
            }
            message.setRecipients(Message.RecipientType.TO, sendTo);
        }
        
        if (cc != null) {
            InternetAddress[] copyTo = new InternetAddress[cc.length];
            
            for (int i = 0; i < cc.length; i++) {
                copyTo[i] = new InternetAddress(cc[i]);
                if (log.isDebugEnabled()) {
                    log.debug("copying e-mail to: " + cc[i]);
                }
            }
            message.setRecipients(Message.RecipientType.CC, copyTo);
        }
        
        if (bcc != null) {
            InternetAddress[] copyTo = new InternetAddress[bcc.length];
            
            for (int i = 0; i < bcc.length; i++) {
                copyTo[i] = new InternetAddress(bcc[i]);
                if (log.isDebugEnabled()) {
                    log.debug("blind copying e-mail to: " + bcc[i]);
                }
            }
            message.setRecipients(Message.RecipientType.BCC, copyTo);
        }
        message.setSubject((subject == null) ? "(no subject)" : subject, "UTF-8");
        message.setContent(content, mimeType);
        message.setSentDate(new java.util.Date());
        
        // First collect all the addresses together.
        Address[] remainingAddresses = message.getAllRecipients();
        int nAddresses = remainingAddresses.length;
        boolean bFailedToSome = false;
        
        SendFailedException sendex = new SendFailedException("Unable to send message to some recipients");
        
        Transport transport = mailProvider.getTransport();
        
        // Try to send while there remain some potentially good addresses
        try { 
            do {
                // Avoid a loop if we are stuck
                nAddresses = remainingAddresses.length;

                try {
                    // Send to the list of remaining addresses, ignoring the addresses attached to the message
                    transport.sendMessage(message, remainingAddresses);
                } catch(SendFailedException ex) {
                    bFailedToSome=true;
                    sendex.setNextException(ex);

                    // Extract the remaining potentially good addresses
                    remainingAddresses=ex.getValidUnsentAddresses();
                }
            } while (remainingAddresses!=null && remainingAddresses.length>0 
                    && remainingAddresses.length!=nAddresses);
            
        } finally {
            transport.close();
        }
        
        if (bFailedToSome) {
            throw sendex;
        }
    }
    
    
    /**
     * This method is used to send a Text Message.
     *
     * @param from e-mail address of sender
     * @param to e-mail addresses of recipients
     * @param cc e-mail address of cc recipients
     * @param bcc e-mail address of bcc recipients
     * @param subject subject of e-mail
     * @param content the body of the e-mail
     * @throws MessagingException the exception to indicate failure
     */
    public static void sendTextMessage(String from, String[] to, String[] cc, String[] bcc,
                                       String subject, String content) throws MessagingException {
        sendMessage(from, to, cc, bcc, subject, content, "text/plain; charset=utf-8");
    }

    /**
     * This method is used to send a HTML Message
     *
     * @param from e-mail address of sender
     * @param to e-mail address(es) of recipients
     * @param subject subject of e-mail
     * @param content the body of the e-mail
     * @throws MessagingException the exception to indicate failure
     */
    public static void sendHTMLMessage(String from, String[] to, String[] cc, String[] bcc, String subject,
                                       String content) throws MessagingException {
        sendMessage(from, to, cc, bcc, subject, content, "text/html; charset=utf-8");
    }

    /**
     * An exception thrown if there is a problem sending an email.
     */
    public class MailingException extends WebloggerException {
        public MailingException(Throwable t) {
            super(t);
        }
    }
}
