/*******************************************************************************
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  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.
 *******************************************************************************/
package org.ofbiz.service.mail;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.sql.Timestamp;
import java.util.List;
import java.util.Properties;

import javax.mail.Address;
import javax.mail.BodyPart;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.Part;
import javax.mail.Session;
import javax.mail.internet.MimeMessage;

import javolution.util.FastList;

import org.ofbiz.base.conversion.AbstractConverter;
import org.ofbiz.base.conversion.ConversionException;
import org.ofbiz.base.conversion.Converters;
import org.ofbiz.base.util.Debug;
import org.ofbiz.base.util.GeneralRuntimeException;
import org.ofbiz.base.util.UtilDateTime;

@SuppressWarnings("serial")
public class MimeMessageWrapper implements java.io.Serializable {

    public static final String module = MimeMessageWrapper.class.getName();
    protected transient MimeMessage message = null;
    protected transient Session session = null;
    protected Properties mailProperties = null;
    protected String contentType = null;
    protected byte[] serializedBytes = null;
    protected int parts = 0;

    public MimeMessageWrapper(Session session, MimeMessage message) {
        this(session);
        this.setMessage(message);
    }

    public MimeMessageWrapper(Session session) {
        this.setSession(session);
    }

    public void setSession(Session session) {
        this.session = session;
        this.mailProperties = session.getProperties();
    }

    public synchronized Session getSession() {
        if (session == null) {
            session = Session.getInstance(mailProperties, null);
        }
        return session;
    }

    public void setMessage(MimeMessage message) {
        if (message != null) {
            // serialize the message
            this.message = message;
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            try {
                message.writeTo(baos);
                baos.flush();
                serializedBytes = baos.toByteArray();
                this.contentType = message.getContentType();

                // see if this is a multi-part message
                Object content = message.getContent();
                if (content instanceof Multipart) {
                    Multipart mp = (Multipart) content;
                    this.parts = mp.getCount();
                } else {
                    this.parts = 0;
                }
            } catch (MessagingException e) {
                Debug.logError(e, module);
            } catch (IOException e) {
                Debug.logError(e, module);
            } finally {
                try {
                    baos.close();
                } catch (IOException e) {
                    Debug.logError(e, module);
                }
            }
        }
    }

    public synchronized MimeMessage getMessage() {
        if (message == null) {
            // deserialize the message
            if (serializedBytes != null) {
                ByteArrayInputStream bais = new ByteArrayInputStream(serializedBytes);
                try {
                    message = new MimeMessage(this.getSession(), bais);
                } catch (MessagingException e) {
                    Debug.logError(e, module);
                    throw new GeneralRuntimeException(e.getMessage(), e);
                }
            }
        }
        return message;
    }

    public String getFirstHeader(String header) {
        String[] headers = getHeader(header);
        if (headers != null && headers.length > 0) {
            return headers[0];
        } else {
            return null;
        }
    }
    public String[] getHeader(String header) {
        MimeMessage message = getMessage();
        try {
            return message.getHeader(header);
        } catch (MessagingException e) {
            Debug.logError(e, module);
            return null;
        }
    }

    public Address[] getFrom() {
        MimeMessage message = getMessage();
        try {
            return message.getFrom();
        } catch (MessagingException e) {
            Debug.logError(e, module);
            return null;
        }
    }

    public Address[] getTo() {
        MimeMessage message = getMessage();
        try {
            return message.getRecipients(MimeMessage.RecipientType.TO);
        } catch (MessagingException e) {
            Debug.logError(e, module);
            return null;
        }
    }

    public Address[] getCc() {
        MimeMessage message = getMessage();
        try {
            return message.getRecipients(MimeMessage.RecipientType.CC);
        } catch (MessagingException e) {
            Debug.logError(e, module);
            return null;
        }
    }

    public Address[] getBcc() {
        MimeMessage message = getMessage();
        try {
            return message.getRecipients(MimeMessage.RecipientType.BCC);
        } catch (MessagingException e) {
            Debug.logError(e, module);
            return null;
        }
    }

    public String getSubject() {
        MimeMessage message = getMessage();
        try {
            return message.getSubject();
        } catch (MessagingException e) {
            Debug.logError(e, module);
            return null;
        }
    }

    public String getMessageId() {
        MimeMessage message = getMessage();
        try {
            return message.getMessageID();
        } catch (MessagingException e) {
            Debug.logError(e, module);
            return null;
        }
    }

    public Timestamp getSentDate() {
        MimeMessage message = getMessage();
        try {
            return UtilDateTime.toTimestamp(message.getSentDate());
        } catch (MessagingException e) {
            Debug.logError(e, module);
            return null;
        }
    }

    public Timestamp getReceivedDate() {
        MimeMessage message = getMessage();
        try {
            return UtilDateTime.toTimestamp(message.getReceivedDate());
        } catch (MessagingException e) {
            Debug.logError(e, module);
            return null;
        }
    }

    public String getContentType() {
        return contentType;
    }

    public int getMainPartCount() {
        return this.parts;
    }

    public int getSubPartCount(int index) {
        BodyPart part = getPart(Integer.toString(index));
        try {
            Object content = part.getContent();
            if (content instanceof Multipart) {
                return ((Multipart) content).getCount();
            } else {
                return 0;
            }
        } catch (Exception e) {
            Debug.logError(e, module);
            return -1;
        }
    }

    public List<String> getAttachmentIndexes() {
        List<String> attachments = FastList.newInstance();
        if (getMainPartCount() == 0) { // single part message (no attachments)
            return attachments;
        } else {
            for (int i = 0; i < getMainPartCount(); i++) {
                int subPartCount = getSubPartCount(i);
                String idx = Integer.toString(i);
                if (subPartCount > 0) {
                    for (int si = 0; si < subPartCount; si++) {
                        String sidx = idx + "." + Integer.toString(si);
                        if (getPartDisposition(sidx) != null && (getPartDisposition(sidx).equalsIgnoreCase(Part.ATTACHMENT) ||
                                getPartDisposition(sidx).equalsIgnoreCase(Part.INLINE))) {
                            attachments.add(sidx);
                        }
                    }
                } else {
                    if (getPartDisposition(idx) != null && (getPartDisposition(idx).equalsIgnoreCase(Part.ATTACHMENT) ||
                            getPartDisposition(idx).equalsIgnoreCase(Part.INLINE))) {
                        attachments.add(idx);
                    }
                }
            }
            return attachments;
        }
    }

    public String getMessageBody() {
        MimeMessage message = getMessage();
        if (getMainPartCount() == 0) { // single part message
            try {
                Object content = message.getContent();
                return getContentText(content);
            } catch (Exception e) {
                Debug.logError(e, module);
                return null;
            }
        } else { // multi-part message
            StringBuffer body = new StringBuffer();
            for (int i = 0; i < getMainPartCount(); i++) {
                int subPartCount = getSubPartCount(i);
                String idx = Integer.toString(i);
                if (subPartCount > 0) {
                    for (int si = 0; si < subPartCount; si++) {
                        String sidx = idx + "." + Integer.toString(si);
                        if (getPartContentType(sidx) != null && getPartContentType(sidx).toLowerCase().startsWith("text")) {
                            if (getPartDisposition(sidx) == null || getPartDisposition(sidx).equals(Part.INLINE)) {
                                body.append(getPartText(sidx)).append("\n");
                            }
                        }
                    }
                } else {
                    if (getPartContentType(idx) != null && getPartContentType(idx).toLowerCase().startsWith("text")) {
                        // make sure the part isn't an attachment
                        if (getPartDisposition(idx) == null || getPartDisposition(idx).equals(Part.INLINE)) {
                            body.append(getPartText(idx)).append("\n");
                        }
                    }
                }
            }
            return body.toString();
        }
    }

    public String getMessageBodyContentType() {
        String contentType = getContentType();
        if (contentType != null && contentType.toLowerCase().startsWith("text")) {
            return contentType;
        } else {
            for (int i = 0; i < getMainPartCount(); i++) {
                int subPartCount = getSubPartCount(i);
                String idx = Integer.toString(i);
                if (subPartCount > 0) {
                    for (int si = 0; si < subPartCount; si++) {
                        String sidx = idx + "." + Integer.toString(si);
                        if (getPartContentType(sidx) != null && getPartContentType(sidx).toLowerCase().startsWith("text")) {
                            if (getPartDisposition(sidx) == null || getPartDisposition(sidx).equals(Part.INLINE)) {
                                return getPartContentType(sidx);
                            }
                        }
                    }
                } else {
                    if (getPartContentType(idx) != null && getPartContentType(idx).toLowerCase().startsWith("text")) {
                        // make sure the part isn't an attachment
                        if (getPartDisposition(idx) == null || getPartDisposition(idx).equals(Part.INLINE)) {
                            return getPartContentType(idx);
                        }
                    }
                }
            }
        }
        return "text/html";
    }

    public String getMessageRawText() {
        MimeMessage message = getMessage();
        try {
            return getTextFromStream(message.getInputStream());
        } catch (Exception e) {
            Debug.logError(e, module);
            return null;
        }
    }

    public String getPartDescription(String index) {
        BodyPart part = getPart(index);
        if (part != null) {
            try {
                return part.getDescription();
            } catch (MessagingException e) {
                Debug.logError(e, module);
                return null;
            }
        } else {
            return null;
        }
    }

    public String getPartContentType(String index) {
        BodyPart part = getPart(index);
        if (part != null) {
            try {
                return part.getContentType();
            } catch (MessagingException e) {
                Debug.logError(e, module);
                return null;
            }
        } else {
            return null;
        }
    }

    public String getPartDisposition(String index) {
        BodyPart part = getPart(index);
        if (part != null) {
            try {
                return part.getDisposition();
            } catch (MessagingException e) {
                Debug.logError(e, module);
                return null;
            }
        } else {
            return null;
        }
    }

    public String getPartFilename(String index) {
        BodyPart part = getPart(index);
        if (part != null) {
            try {
                return part.getFileName();
            } catch (MessagingException e) {
                Debug.logError(e, module);
                return null;
            }
        } else {
            return null;
        }
    }

    public ByteBuffer getPartByteBuffer(String index) {
        BodyPart part = getPart(index);
        if (part != null) {
            try {
                InputStream stream = part.getInputStream();
                return getByteBufferFromStream(stream);
            } catch (Exception e) {
                Debug.logError(e, module);
                return null;
            }
        } else {
            return null;
        }
    }

    public String getPartText(String index) {
        BodyPart part = getPart(index);
        if (part != null) {
            try {
                return getContentText(part.getContent());
            } catch (Exception e) {
                Debug.logError(e, module);
                return null;
            }
        } else {
            return null;
        }
    }

    public String getPartRawText(String index) {
        BodyPart part = getPart(index);
        if (part != null) {
            try {
                return getTextFromStream(part.getInputStream());
            } catch (Exception e) {
                Debug.logError(e, module);
                return null;
            }
        } else {
            return null;
        }
    }

    public BodyPart getPart(String indexStr) {
        int mainIndex, subIndex;
        try {
            if (indexStr.indexOf(".") == -1) {
                mainIndex = Integer.parseInt(indexStr);
                subIndex = -1;
            } else {
                String[] indexSplit = indexStr.split("\\.");
                mainIndex = Integer.parseInt(indexSplit[0]);
                subIndex = Integer.parseInt(indexSplit[1]);
            }
        } catch (NumberFormatException e) {
            Debug.logError(e, "Illegal index string format. Should be part 'dot' subpart: " + indexStr, module);
            return null;
        } catch (ArrayIndexOutOfBoundsException e) {
            Debug.logError(e, "Illegal index string format. Should be part 'dot' subpart: " + indexStr, module);
            return null;
        }

        if (getMainPartCount() > 0 && getMainPartCount() > mainIndex) {
            MimeMessage message = this.getMessage();
            try {
                Multipart mp = (Multipart) message.getContent();
                if (subIndex == -1) {
                    return mp.getBodyPart(mainIndex);
                } else {
                    BodyPart part = mp.getBodyPart(mainIndex);
                    int subPartCount = getSubPartCount(mainIndex);
                    if (subPartCount > subIndex) {
                        Multipart sp = (Multipart) part.getContent();
                        return sp.getBodyPart(subIndex);
                    } else {
                        Debug.logWarning("Requested a subpart [" + subIndex + "] which deos not exist; only [" + getSubPartCount(mainIndex) + "] parts", module);
                        // there is no sub part to find
                        return part;
                    }
                }
            } catch (MessagingException e) {
                Debug.logError(e, module);
                return null;
            } catch (IOException e) {
                Debug.logError(e, module);
                return null;
            }
        } else {
            Debug.logWarning("Requested a part [" + mainIndex + "] which deos not exist; only [" + getMainPartCount() + "] parts", module);
            return null;
        }
    }

    protected String getContentText(Object content) {
        if (content == null) return null;
        if (content instanceof String) {
            return (String) content;
        } else if (content instanceof InputStream) {
            return getTextFromStream((InputStream) content);
        } else if (content instanceof Message) {
            try {
                return getTextFromStream(((Message) content).getInputStream());
            } catch (Exception e) {
                Debug.logError(e, module);
                return null;
            }
        } else {
            Debug.logWarning("Content was not a string or a stream; no known handler -- " + content.toString(), module);
            return null;
        }
    }

    protected String getTextFromStream(InputStream stream) {
        StringBuilder builder = new StringBuilder();
        byte[] buffer = new byte[4096];
        try {
            for (int n; (n = stream.read(buffer)) != -1;) {
                builder.append(new String(buffer, 0, n));
            }
        } catch (IOException e) {
            Debug.logError(e, module);
            return null;
        }
        return builder.toString();
    }

    protected ByteBuffer getByteBufferFromStream(InputStream stream) {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        byte[] buffer = new byte[4096];
        try {
            for (int n; (n = stream.read(buffer)) != -1;) {
                baos.write(buffer, 0, n);
            }
        } catch (IOException e) {
            Debug.logError(e, module);
            return null;
        }

        return ByteBuffer.wrap(baos.toByteArray());
    }

    static {
        Converters.registerConverter(new MimeMessageToString<String>());
    }

    /**
     * Convert MimeMessageWrapper to String. This is used when sending emails.
     * 
     */
    private static class MimeMessageToString<E> extends AbstractConverter<MimeMessageWrapper, String> {
        public MimeMessageToString() {
            super(MimeMessageWrapper.class, String.class);
        }

        public String convert(MimeMessageWrapper obj) throws ConversionException {
            return obj.toString();
        }
    }
}
