/*******************************************************************************
 * 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.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.sql.Timestamp;
import java.util.LinkedList;
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 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 = new LinkedList<String>();
        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();
        }
    }
}
