/*
 * Copyright (C) 2001-2004 Red Hat Inc. All Rights Reserved.
 *
 * The contents of this file are subject to the CCM Public
 * License (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.redhat.com/licenses/ccmpl.html.
 *
 * Software distributed under the License is distributed on an
 * "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express
 * or implied. See the License for the specific language
 * governing rights and limitations under the License.
 *
 */
package com.arsdigita.notification;

import com.arsdigita.domain.DataObjectNotFoundException;
import com.arsdigita.domain.ObservableDomainObject;
import com.arsdigita.kernel.Party;
import com.arsdigita.mail.Mail;
import com.arsdigita.messaging.Message;
import com.arsdigita.messaging.MessagePart;
import com.arsdigita.util.MessageType;
import com.arsdigita.persistence.OID;
import com.arsdigita.util.HtmlToText;
import com.arsdigita.util.StringUtils;
import java.math.BigDecimal;
import java.util.Iterator;
import javax.mail.MessagingException;
import org.apache.log4j.Logger;


/**
 * Represents a notification that has been transferred to the outbound
 * message queue.  During processing, this class is used to retrieve
 * information necessary to convert the notification into an outbound
 * email message.
 *
 * @author David Dao
 * @version $Id: //core-platform/dev/src/com/arsdigita/notification/QueueItem.java#9 $
 */

class QueueItem extends ObservableDomainObject
    implements NotificationConstants
{
    // Base DataObject type

    public static final String BASE_DATA_OBJECT_TYPE =
        QueueItem.class.getName();

    private static final Logger s_log =
        Logger.getLogger(QueueItem.class);

    private static HtmlToText s_htmlToText =
        new HtmlToText();

    /**
     * The message object contained by this notification.  Retrieved
     * once from the database and cached.
     */

    private Message m_message;

    /**
     * Creates a QueueItem from an OID.
     */

    QueueItem(OID oid) throws DataObjectNotFoundException {
        super(oid);
    }

    /**
     * Creates a QueueItem from a Notification and recipient.
     */

    QueueItem(Notification n, Party to) {
        super(BASE_DATA_OBJECT_TYPE);
        set(REQUEST_ID, n.getID());
        set(PARTY_TO, to.getID());
    }

    /**
     * Set the success flag for this notification.
     */

    void setSuccess(Boolean b) {
        set(SUCCESS, b);
    }

    /**
     * Gets the message object contained by this notification.
     */

    Message getMessage()
        throws DataObjectNotFoundException
    {
        if (m_message == null) {
            m_message = new Message((BigDecimal) get(MESSAGE_ID));
        }
        return m_message;
    }

    /**
     * Returns the email address of the recipient as a String.
     */

    String getTo() {
        return (String) get(PARTY_TO_ADDR);
    }

    /**
     * Returns the email address of the sender as a String.
     */

    String getFrom()
        throws DataObjectNotFoundException
    {
        return getMessage().getFrom().getPrimaryEmail().toString();
    }

    /**
     * Returns the subject of the notification.
     */

    String getSubject()
        throws DataObjectNotFoundException
    {
        return getMessage().getSubject();
    }

    /**
     * Gets the header for this notification.
     */

    private String getHeader() {
        return StringUtils.nullToEmptyString((String) get(HEADER));
    }

    /**
     * Gets the signature for this notification.
     */

    private String getSignature() {
        return StringUtils.nullToEmptyString((String) get(SIGNATURE));
    }

    /**
     * Returns the body of the message. This method constructs the
     * body of the email by combining the body of the underlying
     * message object with the specified header and signature for the
     * notification.  It then converts the entire message to plain
     * text before sending using {@link HtmlToText}.
     *
     * @return a plain text message to send as email to a user
     */

    String getBody() throws DataObjectNotFoundException {

        Message msg = getMessage();

        String body;
        if (msg.isMimeType(MessageType.TEXT_HTML)) {
            body = s_htmlToText.convert(msg.getBody());
        } else {
            body = StringUtils.wrap(msg.getBody());
        }

        StringBuffer sb = new StringBuffer();
        sb.append(StringUtils.addNewline(getHeader()));
        sb.append(StringUtils.addNewline(body));
        sb.append(StringUtils.addNewline(getSignature()));
        return sb.toString();
    }

    /**
     * Transfer any attachments from the message contained by this
     * notification to a given Mail message.
     *
     * @param mail the Mail to add attachments to
     */

    void addAttachments(Mail mail)
        throws MessagingException
    {
        Message msg;
        try {
            msg = getMessage();
        } catch (DataObjectNotFoundException ex) {
            return;
        }

        if (msg.getAttachmentCount() > 0) {
            Iterator iter = msg.getAttachments();
            while (iter.hasNext()) {
                MessagePart part = (MessagePart) iter.next();
                mail.attach(part.getDataHandler(),
                            part.getDescription(),
                            part.getDisposition());

            }
        }
    }

    BigDecimal getRetryCount() {
        return (BigDecimal) get(RETRY_COUNT);
    }

    void setRetryCount(BigDecimal i) {
        set(RETRY_COUNT, i);
    }

    void incrRetryCount() {
        set(RETRY_COUNT, getRetryCount().add(new BigDecimal(1)));
    }

}
