/*
* Copyright (C) 2013 Samsung System LSI
* Licensed 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 com.android.bluetooth.map;

import android.text.util.Rfc822Token;
import android.text.util.Rfc822Tokenizer;
import android.util.Base64;
import android.util.Log;

import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.nio.charset.IllegalCharsetNameException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.Locale;
import java.util.UUID;

public class BluetoothMapbMessageMime extends BluetoothMapbMessage {

    public static class MimePart {
        public long mId = INVALID_VALUE;   /* The _id from the content provider, can be used to
                                            * sort the parts if needed */
        public String mContentType = null; /* The mime type, e.g. text/plain */
        public String mContentId = null;
        public String mContentLocation = null;
        public String mContentDisposition = null;
        public String mPartName = null;    /* e.g. text_1.txt*/
        public String mCharsetName = null; /* This seems to be a number e.g. 106 for UTF-8
                                              CharacterSets holds a method for the mapping. */
        public String mFileName = null;     /* Do not seem to be used */
        public byte[] mData = null;        /* The raw un-encoded data e.g. the raw
                                            * jpeg data or the text.getBytes("utf-8") */


        public String getDataAsString() {
            String result = null;
            String charset = mCharsetName;
            // Figure out if we support the charset, else fall back to UTF-8, as this is what
            // the MAP specification suggest to use, and is compatible with US-ASCII.
            if (charset == null) {
                charset = "UTF-8";
            } else {
                charset = charset.toUpperCase();
                try {
                    if (!Charset.isSupported(charset)) {
                        charset = "UTF-8";
                    }
                } catch (IllegalCharsetNameException e) {
                    Log.w(TAG, "Received unknown charset: " + charset + " - using UTF-8.");
                    charset = "UTF-8";
                }
            }
            try {
                result = new String(mData, charset);
            } catch (UnsupportedEncodingException e) {
                /* This cannot happen unless Charset.isSupported() is out of sync with String */
                try {
                    result = new String(mData, "UTF-8");
                } catch (UnsupportedEncodingException e2) {
                    Log.e(TAG, "getDataAsString: " + e);
                }
            }
            return result;
        }

        public void encode(StringBuilder sb, String boundaryTag, boolean last)
                throws UnsupportedEncodingException {
            sb.append("--").append(boundaryTag).append("\r\n");
            if (mContentType != null) {
                sb.append("Content-Type: ").append(mContentType);
            }
            if (mCharsetName != null) {
                sb.append("; ").append("charset=\"").append(mCharsetName).append("\"");
            }
            sb.append("\r\n");
            if (mContentLocation != null) {
                sb.append("Content-Location: ").append(mContentLocation).append("\r\n");
            }
            if (mContentId != null) {
                sb.append("Content-ID: ").append(mContentId).append("\r\n");
            }
            if (mContentDisposition != null) {
                sb.append("Content-Disposition: ").append(mContentDisposition).append("\r\n");
            }
            if (mData != null) {
                /* TODO: If errata 4176 is adopted in the current form (it is not in either 1.1
                or 1.2),
                the below use of UTF-8 is not allowed, Base64 should be used for text. */

                if (mContentType != null && (mContentType.toUpperCase().contains("TEXT")
                        || mContentType.toUpperCase().contains("SMIL"))) {
                    String text = new String(mData, "UTF-8");
                    if (text.getBytes().length == text.getBytes("UTF-8").length) {
                        /* Add the header split empty line */
                        sb.append("Content-Transfer-Encoding: 8BIT\r\n\r\n");
                    } else {
                        /* Add the header split empty line */
                        sb.append("Content-Transfer-Encoding: Quoted-Printable\r\n\r\n");
                        text = BluetoothMapUtils.encodeQuotedPrintable(mData);
                    }
                    sb.append(text).append("\r\n");
                } else {
                    /* Add the header split empty line */
                    sb.append("Content-Transfer-Encoding: Base64\r\n\r\n");
                    sb.append(Base64.encodeToString(mData, Base64.DEFAULT)).append("\r\n");
                }
            }
            if (last) {
                sb.append("--").append(boundaryTag).append("--").append("\r\n");
            }
        }

        public void encodePlainText(StringBuilder sb) throws UnsupportedEncodingException {
            if (mContentType != null && mContentType.toUpperCase().contains("TEXT")) {
                String text = new String(mData, "UTF-8");
                if (text.getBytes().length != text.getBytes("UTF-8").length) {
                    text = BluetoothMapUtils.encodeQuotedPrintable(mData);
                }
                sb.append(text).append("\r\n");
            } else if (mContentType != null && mContentType.toUpperCase().contains("/SMIL")) {
                /* Skip the smil.xml, as no-one knows what it is. */
            } else {
                /* Not a text part, just print the filename or part name if they exist. */
                if (mPartName != null) {
                    sb.append("<").append(mPartName).append(">\r\n");
                } else {
                    sb.append("<").append("attachment").append(">\r\n");
                }
            }
        }
    }

    private long mDate = INVALID_VALUE;
    private String mSubject = null;
    private ArrayList<Rfc822Token> mFrom = null;   // Shall not be empty
    private ArrayList<Rfc822Token> mSender = null;   // Shall not be empty
    private ArrayList<Rfc822Token> mTo = null;     // Shall not be empty
    private ArrayList<Rfc822Token> mCc = null;     // Can be empty
    private ArrayList<Rfc822Token> mBcc = null;    // Can be empty
    private ArrayList<Rfc822Token> mReplyTo = null; // Can be empty
    private String mMessageId = null;
    private ArrayList<MimePart> mParts = null;
    private String mContentType = null;
    private String mBoundary = null;
    private boolean mTextonly = false;
    private boolean mIncludeAttachments;
    private boolean mHasHeaders = false;
    private String mMyEncoding = null;

    private String getBoundary() {
        // Include "=_" as these cannot occur in quoted printable text
        if (mBoundary == null) {
            mBoundary = "--=_" + UUID.randomUUID();
        }
        return mBoundary;
    }

    /**
     * @return the parts
     */
    public ArrayList<MimePart> getMimeParts() {
        return mParts;
    }

    public String getMessageAsText() {
        StringBuilder sb = new StringBuilder();
        if (mSubject != null && !mSubject.isEmpty()) {
            sb.append("<Sub:").append(mSubject).append("> ");
        }
        if (mParts != null) {
            for (MimePart part : mParts) {
                if (part.mContentType.toUpperCase().contains("TEXT")) {
                    sb.append(new String(part.mData));
                }
            }
        }
        return sb.toString();
    }

    public MimePart addMimePart() {
        if (mParts == null) {
            mParts = new ArrayList<BluetoothMapbMessageMime.MimePart>();
        }
        MimePart newPart = new MimePart();
        mParts.add(newPart);
        return newPart;
    }

    public String getDateString() {
        SimpleDateFormat format = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss Z", Locale.US);
        Date dateObj = new Date(mDate);
        return format.format(dateObj); // Format according to RFC 2822 page 14
    }

    public long getDate() {
        return mDate;
    }

    public void setDate(long date) {
        this.mDate = date;
    }

    public String getSubject() {
        return mSubject;
    }

    public void setSubject(String subject) {
        this.mSubject = subject;
    }

    public ArrayList<Rfc822Token> getFrom() {
        return mFrom;
    }

    public void setFrom(ArrayList<Rfc822Token> from) {
        this.mFrom = from;
    }

    public void addFrom(String name, String address) {
        if (this.mFrom == null) {
            this.mFrom = new ArrayList<Rfc822Token>(1);
        }
        this.mFrom.add(new Rfc822Token(name, address, null));
    }

    public ArrayList<Rfc822Token> getSender() {
        return mSender;
    }

    public void setSender(ArrayList<Rfc822Token> sender) {
        this.mSender = sender;
    }

    public void addSender(String name, String address) {
        if (this.mSender == null) {
            this.mSender = new ArrayList<Rfc822Token>(1);
        }
        this.mSender.add(new Rfc822Token(name, address, null));
    }

    public ArrayList<Rfc822Token> getTo() {
        return mTo;
    }

    public void setTo(ArrayList<Rfc822Token> to) {
        this.mTo = to;
    }

    public void addTo(String name, String address) {
        if (this.mTo == null) {
            this.mTo = new ArrayList<Rfc822Token>(1);
        }
        this.mTo.add(new Rfc822Token(name, address, null));
    }

    public ArrayList<Rfc822Token> getCc() {
        return mCc;
    }

    public void setCc(ArrayList<Rfc822Token> cc) {
        this.mCc = cc;
    }

    public void addCc(String name, String address) {
        if (this.mCc == null) {
            this.mCc = new ArrayList<Rfc822Token>(1);
        }
        this.mCc.add(new Rfc822Token(name, address, null));
    }

    public ArrayList<Rfc822Token> getBcc() {
        return mBcc;
    }

    public void setBcc(ArrayList<Rfc822Token> bcc) {
        this.mBcc = bcc;
    }

    public void addBcc(String name, String address) {
        if (this.mBcc == null) {
            this.mBcc = new ArrayList<Rfc822Token>(1);
        }
        this.mBcc.add(new Rfc822Token(name, address, null));
    }

    public ArrayList<Rfc822Token> getReplyTo() {
        return mReplyTo;
    }

    public void setReplyTo(ArrayList<Rfc822Token> replyTo) {
        this.mReplyTo = replyTo;
    }

    public void addReplyTo(String name, String address) {
        if (this.mReplyTo == null) {
            this.mReplyTo = new ArrayList<Rfc822Token>(1);
        }
        this.mReplyTo.add(new Rfc822Token(name, address, null));
    }

    public void setMessageId(String messageId) {
        this.mMessageId = messageId;
    }

    public String getMessageId() {
        return mMessageId;
    }

    public void setContentType(String contentType) {
        this.mContentType = contentType;
    }

    public String getContentType() {
        return mContentType;
    }

    public void setTextOnly(boolean textOnly) {
        this.mTextonly = textOnly;
    }

    public boolean getTextOnly() {
        return mTextonly;
    }

    public void setIncludeAttachments(boolean includeAttachments) {
        this.mIncludeAttachments = includeAttachments;
    }

    public boolean getIncludeAttachments() {
        return mIncludeAttachments;
    }

    public void updateCharset() {
        if (mParts != null) {
            mCharset = null;
            for (MimePart part : mParts) {
                if (part.mContentType != null && part.mContentType.toUpperCase().contains("TEXT")) {
                    mCharset = "UTF-8";
                    if (V) {
                        Log.v(TAG, "Charset set to UTF-8");
                    }
                    break;
                }
            }
        }
    }

    public int getSize() {
        int messageSize = 0;
        if (mParts != null) {
            for (MimePart part : mParts) {
                messageSize += part.mData.length;
            }
        }
        return messageSize;
    }

    /**
     * Encode an address header, and perform folding if needed.
     * @param sb The stringBuilder to write to
     * @param headerName The RFC 2822 header name
     * @param addresses the reformatted address substrings to encode.
     */
    public void encodeHeaderAddresses(StringBuilder sb, String headerName,
            ArrayList<Rfc822Token> addresses) {
        /* TODO: Do we need to encode the addresses if they contain illegal characters?
         * This depends of the outcome of errata 4176. The current spec. states to use UTF-8
         * where possible, but the RFCs states to use US-ASCII for the headers - hence encoding
         * would be needed to support non US-ASCII characters. But the MAP spec states not to
         * use any encoding... */
        int partLength, lineLength = 0;
        lineLength += headerName.getBytes().length;
        sb.append(headerName);
        for (Rfc822Token address : addresses) {
            partLength = address.toString().getBytes().length + 1;
            // Add folding if needed
            if (lineLength + partLength >= 998 /* max line length in RFC2822 */) {
                sb.append("\r\n "); // Append a FWS (folding whitespace)
                lineLength = 0;
            }
            sb.append(address.toString()).append(";");
            lineLength += partLength;
        }
        sb.append("\r\n");
    }

    public void encodeHeaders(StringBuilder sb) throws UnsupportedEncodingException {
        /* TODO: From RFC-4356 - about the RFC-(2)822 headers:
         *    "Current Internet Message format requires that only 7-bit US-ASCII
         *     characters be present in headers.  Non-7-bit characters in an address
         *     domain must be encoded with [IDN].  If there are any non-7-bit
         *     characters in the local part of an address, the message MUST be
         *     rejected.  Non-7-bit characters elsewhere in a header MUST be encoded
         *     according to [Hdr-Enc]."
         *    We need to add the address encoding in encodeHeaderAddresses, but it is not
         *    straight forward, as it is unclear how to do this.  */
        if (mDate != INVALID_VALUE) {
            sb.append("Date: ").append(getDateString()).append("\r\n");
        }
        /* According to RFC-2822 headers must use US-ASCII, where the MAP specification states
         * UTF-8 should be used for the entire <bmessage-body-content>. We let the MAP specification
         * take precedence above the RFC-2822.
         */
        /* If we are to use US-ASCII anyway, here is the code for it for base64.
          if (subject != null){
            // Use base64 encoding for the subject, as it may contain non US-ASCII characters or
            // other illegal (RFC822 header), and android do not seem to have encoders/decoders
            // for quoted-printables
            sb.append("Subject:").append("=?utf-8?B?");
            sb.append(Base64.encodeToString(subject.getBytes("utf-8"), Base64.DEFAULT));
            sb.append("?=\r\n");
        }*/
        if (mSubject != null) {
            sb.append("Subject: ").append(mSubject).append("\r\n");
        }
        if (mFrom == null) {
            sb.append("From: \r\n");
        }
        if (mFrom != null) {
            encodeHeaderAddresses(sb, "From: ", mFrom); // This includes folding if needed.
        }
        if (mSender != null) {
            encodeHeaderAddresses(sb, "Sender: ", mSender); // This includes folding if needed.
        }
        /* For MMS one recipient(to, cc or bcc) must exists, if none: 'To:  undisclosed-
         * recipients:;' could be used.
         */
        if (mTo == null && mCc == null && mBcc == null) {
            sb.append("To:  undisclosed-recipients:;\r\n");
        }
        if (mTo != null) {
            encodeHeaderAddresses(sb, "To: ", mTo); // This includes folding if needed.
        }
        if (mCc != null) {
            encodeHeaderAddresses(sb, "Cc: ", mCc); // This includes folding if needed.
        }
        if (mBcc != null) {
            encodeHeaderAddresses(sb, "Bcc: ", mBcc); // This includes folding if needed.
        }
        if (mReplyTo != null) {
            encodeHeaderAddresses(sb, "Reply-To: ", mReplyTo); // This includes folding if needed.
        }
        if (mIncludeAttachments) {
            if (mMessageId != null) {
                sb.append("Message-Id: ").append(mMessageId).append("\r\n");
            }
            if (mContentType != null) {
                sb.append("Content-Type: ")
                        .append(mContentType)
                        .append("; boundary=")
                        .append(getBoundary())
                        .append("\r\n");
            }
        }
        // If no headers exists, we still need two CRLF, hence keep it out of the if above.
        sb.append("\r\n");
    }

    /* Notes on MMS
     * ------------
     * According to rfc4356 all headers of a MMS converted to an E-mail must use
     * 7-bit encoding. According the the MAP specification only 8-bit encoding is
     * allowed - hence the bMessage-body should contain no SMTP headers. (Which makes
     * sense, since the info is already present in the bMessage properties.)
     * The result is that no information from RFC4356 is needed, since it does not
     * describe any mapping between MMS content and E-mail content.
     * Suggestion:
     * Clearly state in the MAP specification that
     * only the actual message content should be included in the <bmessage-body-content>.
     * Correct the Example to not include the E-mail headers, and in stead show how to
     * include a picture or another binary attachment.
     *
     * If the headers should be included, clearly state which, as the example clearly shows
     * that some of the headers should be excluded.
     * Additionally it is not clear how to handle attachments. There is a parameter in the
     * get message to include attachments, but since only 8-bit encoding is allowed,
     * (hence neither base64 nor binary) there is no mechanism to embed the attachment in
     * the <bmessage-body-content>.
     *
     * UPDATE: Errata 4176 allows the needed encoding typed inside the <bmessage-body-content>
     * including Base64 and Quoted Printables - hence it is possible to encode non-us-ascii
     * messages - e.g. pictures and utf-8 strings with non-us-ascii content.
     * It have not yet been adopted, but since the comments clearly suggest that it is allowed
     * to use encoding schemes for non-text parts, it is still not clear what to do about non
     * US-ASCII text in the headers.
     * */

    /**
     * Encode the bMessage as a Mime message(MMS/IM)
     * @return
     * @throws UnsupportedEncodingException
     */
    public byte[] encodeMime() throws UnsupportedEncodingException {
        ArrayList<byte[]> bodyFragments = new ArrayList<byte[]>();
        StringBuilder sb = new StringBuilder();
        int count = 0;
        String mimeBody;

        mEncoding = "8BIT"; // The encoding used

        encodeHeaders(sb);
        if (mParts != null) {
            if (!getIncludeAttachments()) {
                for (MimePart part : mParts) {
                    /* We call encode on all parts, to include a tag,
                     * where an attachment is missing. */
                    part.encodePlainText(sb);
                }
            } else {
                for (MimePart part : mParts) {
                    count++;
                    part.encode(sb, getBoundary(), (count == mParts.size()));
                }
            }
        }

        mimeBody = sb.toString();

        if (mimeBody != null) {
            // Replace any occurrences of END:MSG with \END:MSG
            String tmpBody = mimeBody.replaceAll("END:MSG", "/END\\:MSG");
            bodyFragments.add(tmpBody.getBytes("UTF-8"));
        } else {
            bodyFragments.add(new byte[0]);
        }

        return encodeGeneric(bodyFragments);
    }


    /**
     * Try to parse the hdrPart string as e-mail headers.
     * @param hdrPart The string to parse.
     * @return Null if the entire string were e-mail headers. The part of the string in which
     * no headers were found.
     */
    private String parseMimeHeaders(String hdrPart) {
        String[] headers = hdrPart.split("\r\n");
        if (D) {
            Log.d(TAG, "Header count=" + headers.length);
        }
        String header;
        mHasHeaders = false;

        for (int i = 0, c = headers.length; i < c; i++) {
            header = headers[i];
            if (D) {
                Log.d(TAG, "Header[" + i + "]: " + header);
            }
            /* We need to figure out if any headers are present, in cases where devices do
             * not follow the e-mail RFCs.
             * Skip empty lines, and then parse headers until a non-header line is found,
             * at which point we treat the remaining as plain text.
             */
            if (header.trim().isEmpty()) {
                continue;
            }
            String[] headerParts = header.split(":", 2);
            if (headerParts.length != 2) {
                // We treat the remaining content as plain text.
                StringBuilder remaining = new StringBuilder();
                for (; i < c; i++) {
                    remaining.append(headers[i]);
                }

                return remaining.toString();
            }

            String headerType = headerParts[0].toUpperCase();
            String headerValue = headerParts[1].trim();

            // Address headers
            /* If this is empty, the MSE needs to fill it in before sending the message.
             * This happens when sending the MMS.
             */
            if (headerType.contains("FROM")) {
                headerValue = BluetoothMapUtils.stripEncoding(headerValue);
                Rfc822Token[] tokens = Rfc822Tokenizer.tokenize(headerValue);
                mFrom = new ArrayList<Rfc822Token>(Arrays.asList(tokens));
            } else if (headerType.contains("TO")) {
                headerValue = BluetoothMapUtils.stripEncoding(headerValue);
                Rfc822Token[] tokens = Rfc822Tokenizer.tokenize(headerValue);
                mTo = new ArrayList<Rfc822Token>(Arrays.asList(tokens));
            } else if (headerType.contains("CC")) {
                headerValue = BluetoothMapUtils.stripEncoding(headerValue);
                Rfc822Token[] tokens = Rfc822Tokenizer.tokenize(headerValue);
                mCc = new ArrayList<Rfc822Token>(Arrays.asList(tokens));
            } else if (headerType.contains("BCC")) {
                headerValue = BluetoothMapUtils.stripEncoding(headerValue);
                Rfc822Token[] tokens = Rfc822Tokenizer.tokenize(headerValue);
                mBcc = new ArrayList<Rfc822Token>(Arrays.asList(tokens));
            } else if (headerType.contains("REPLY-TO")) {
                headerValue = BluetoothMapUtils.stripEncoding(headerValue);
                Rfc822Token[] tokens = Rfc822Tokenizer.tokenize(headerValue);
                mReplyTo = new ArrayList<Rfc822Token>(Arrays.asList(tokens));
            } else if (headerType.contains("SUBJECT")) { // Other headers
                mSubject = BluetoothMapUtils.stripEncoding(headerValue);
            } else if (headerType.contains("MESSAGE-ID")) {
                mMessageId = headerValue;
            } else if (headerType.contains("DATE")) {
                /* The date is not needed, as the time stamp will be set in the DB
                 * when the message is send. */
            } else if (headerType.contains("MIME-VERSION")) {
                /* The mime version is not needed */
            } else if (headerType.contains("CONTENT-TYPE")) {
                String[] contentTypeParts = headerValue.split(";");
                mContentType = contentTypeParts[0];
                // Extract the boundary if it exists
                for (int j = 1, n = contentTypeParts.length; j < n; j++) {
                    if (contentTypeParts[j].contains("boundary")) {
                        mBoundary = contentTypeParts[j].split("boundary[\\s]*=", 2)[1].trim();
                        // removing quotes from boundary string
                        if ((mBoundary.charAt(0) == '\"') && (
                                mBoundary.charAt(mBoundary.length() - 1) == '\"')) {
                            mBoundary = mBoundary.substring(1, mBoundary.length() - 1);
                        }
                        if (D) {
                            Log.d(TAG, "Boundary tag=" + mBoundary);
                        }
                    } else if (contentTypeParts[j].contains("charset")) {
                        mCharset = contentTypeParts[j].split("charset[\\s]*=", 2)[1].trim();
                    }
                }
            } else if (headerType.contains("CONTENT-TRANSFER-ENCODING")) {
                mMyEncoding = headerValue;
            } else {
                if (D) {
                    Log.w(TAG, "Skipping unknown header: " + headerType + " (" + header + ")");
                }
            }
        }
        return null;
    }

    private void parseMimePart(String partStr) {
        String[] parts = partStr.split("\r\n\r\n", 2); // Split the header from the body
        MimePart newPart = addMimePart();
        String partEncoding = mMyEncoding; /* Use the overall encoding as default */
        String body;

        String[] headers = parts[0].split("\r\n");
        if (D) {
            Log.d(TAG, "parseMimePart: headers count=" + headers.length);
        }

        if (parts.length != 2) {
            body = partStr;
        } else {
            for (String header : headers) {
                // Skip empty lines(the \r\n after the boundary tag) and endBoundary tags
                if ((header.length() == 0) || (header.trim().isEmpty()) || header.trim()
                        .equals("--")) {
                    continue;
                }

                String[] headerParts = header.split(":", 2);
                if (headerParts.length != 2) {
                    if (D) {
                        Log.w(TAG, "part-Header not formatted correctly: ");
                    }
                    continue;
                }
                if (D) {
                    Log.d(TAG, "parseMimePart: header=" + header);
                }
                String headerType = headerParts[0].toUpperCase();
                String headerValue = headerParts[1].trim();
                if (headerType.contains("CONTENT-TYPE")) {
                    String[] contentTypeParts = headerValue.split(";");
                    newPart.mContentType = contentTypeParts[0];
                    // Extract the boundary if it exists
                    for (int j = 1, n = contentTypeParts.length; j < n; j++) {
                        String value = contentTypeParts[j].toLowerCase();
                        if (value.contains("charset")) {
                            newPart.mCharsetName = value.split("charset[\\s]*=", 2)[1].trim();
                        }
                    }
                } else if (headerType.contains("CONTENT-LOCATION")) {
                    // This is used if the smil refers to a file name in its src
                    newPart.mContentLocation = headerValue;
                    newPart.mPartName = headerValue;
                } else if (headerType.contains("CONTENT-TRANSFER-ENCODING")) {
                    partEncoding = headerValue;
                } else if (headerType.contains("CONTENT-ID")) {
                    // This is used if the smil refers to a cid:<xxx> in it's src
                    newPart.mContentId = headerValue;
                } else if (headerType.contains("CONTENT-DISPOSITION")) {
                    // This is used if the smil refers to a cid:<xxx> in it's src
                    newPart.mContentDisposition = headerValue;
                } else {
                    if (D) {
                        Log.w(TAG, "Skipping unknown part-header: " + headerType + " (" + header
                                + ")");
                    }
                }
            }
            body = parts[1];
            if (body.length() > 2) {
                if (body.charAt(body.length() - 2) == '\r'
                        && body.charAt(body.length() - 2) == '\n') {
                    body = body.substring(0, body.length() - 2);
                }
            }
        }
        // Now for the body
        newPart.mData = decodeBody(body, partEncoding, newPart.mCharsetName);
    }

    private void parseMimeBody(String body) {
        MimePart newPart = addMimePart();
        newPart.mCharsetName = mCharset;
        newPart.mData = decodeBody(body, mMyEncoding, mCharset);
    }

    private byte[] decodeBody(String body, String encoding, String charset) {
        if (encoding != null && encoding.toUpperCase().contains("BASE64")) {
            return Base64.decode(body, Base64.DEFAULT);
        } else if (encoding != null && encoding.toUpperCase().contains("QUOTED-PRINTABLE")) {
            return BluetoothMapUtils.quotedPrintableToUtf8(body, charset);
        } else {
            // TODO: handle other encoding types? - here we simply store the string data as bytes
            try {

                return body.getBytes("UTF-8");
            } catch (UnsupportedEncodingException e) {
                // This will never happen, as UTF-8 is mandatory on Android platforms
            }
        }
        return null;
    }

    private void parseMime(String message) {
        // Check for null String, otherwise NPE will cause BT to crash
        if (message == null) {
            Log.e(TAG, "parseMime called with a NULL message, terminating early");
            return;
        }

        /* Overall strategy for decoding:
         * 1) split on first empty line to extract the header
         * 2) unfold and parse headers
         * 3) split on boundary to split into parts (or use the remaining as a part,
         *    if part is not found)
         * 4) parse each part
         * */
        String[] messageParts;
        String[] mimeParts;
        String remaining = null;
        String messageBody = null;

        message = message.replaceAll("\\r\\n[ \\\t]+", ""); // Unfold
        messageParts = message.split("\r\n\r\n", 2); // Split the header from the body
        if (messageParts.length != 2) {
            // Handle entire message as plain text
            messageBody = message;
        } else {
            remaining = parseMimeHeaders(messageParts[0]);
            // If we have some text not being a header, add it to the message body.
            if (remaining != null) {
                messageBody = remaining + messageParts[1];
                if (D) {
                    Log.d(TAG, "parseMime remaining=" + remaining);
                }
            } else {
                messageBody = messageParts[1];
            }
        }

        if (mBoundary == null) {
            // If the boundary is not set, handle as non-multi-part
            parseMimeBody(messageBody);
            setTextOnly(true);
            if (mContentType == null) {
                mContentType = "text/plain";
            }
            mParts.get(0).mContentType = mContentType;
        } else {
            mimeParts = messageBody.split("--" + mBoundary);
            if (D) {
                Log.d(TAG, "mimePart count=" + mimeParts.length);
            }
            // Part 0 is the message to clients not capable of decoding MIME
            for (int i = 1; i < mimeParts.length - 1; i++) {
                String part = mimeParts[i];
                if (part != null && (part.length() > 0)) {
                    parseMimePart(part);
                }
            }
        }
    }

    /* Notes on SMIL decoding (from http://tools.ietf.org/html/rfc2557):
     * src="filename.jpg" refers to a part with Content-Location: filename.jpg
     * src="cid:1234@hest.net" refers to a part with Content-ID:<1234@hest.net>*/
    @Override
    public void parseMsgPart(String msgPart) {
        parseMime(msgPart);

    }

    @Override
    public void parseMsgInit() {
        // Not used for e-mail

    }

    @Override
    public byte[] encode() throws UnsupportedEncodingException {
        return encodeMime();
    }

}
