/*
 * Copyright (C) 2008-2009 Marc Blank
 * Licensed to The Android Open Source Project.
 *
 * 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.exchange;

import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.net.TrafficStats;
import android.net.Uri;
import android.text.format.DateUtils;

import com.android.emailcommon.TrafficFlags;
import com.android.emailcommon.internet.Rfc822Output;
import com.android.emailcommon.mail.MessagingException;
import com.android.emailcommon.provider.Account;
import com.android.emailcommon.provider.EmailContent.Attachment;
import com.android.emailcommon.provider.EmailContent.Body;
import com.android.emailcommon.provider.EmailContent.BodyColumns;
import com.android.emailcommon.provider.EmailContent.MailboxColumns;
import com.android.emailcommon.provider.EmailContent.Message;
import com.android.emailcommon.provider.EmailContent.MessageColumns;
import com.android.emailcommon.provider.EmailContent.SyncColumns;
import com.android.emailcommon.provider.Mailbox;
import com.android.emailcommon.service.EmailServiceStatus;
import com.android.emailcommon.utility.Utility;
import com.android.exchange.CommandStatusException.CommandStatus;
import com.android.exchange.adapter.Parser;
import com.android.exchange.adapter.Parser.EmptyStreamException;
import com.android.exchange.adapter.Serializer;
import com.android.exchange.adapter.Tags;

import org.apache.http.HttpEntity;
import org.apache.http.HttpStatus;
import org.apache.http.entity.InputStreamEntity;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;

public class EasOutboxService extends EasSyncService {

    public static final int SEND_FAILED = 1;
    public static final String MAILBOX_KEY_AND_NOT_SEND_FAILED =
        MessageColumns.MAILBOX_KEY + "=? and (" + SyncColumns.SERVER_ID + " is null or " +
        SyncColumns.SERVER_ID + "!=" + SEND_FAILED + ')';
    public static final String[] BODY_SOURCE_PROJECTION =
        new String[] {BodyColumns.SOURCE_MESSAGE_KEY};
    public static final String WHERE_MESSAGE_KEY = BodyColumns.MESSAGE_KEY + "=?";

    // This is a normal email (i.e. not one of the other types)
    public static final int MODE_NORMAL = 0;
    // This is a smart reply email
    public static final int MODE_SMART_REPLY = 1;
    // This is a smart forward email
    public static final int MODE_SMART_FORWARD = 2;

    // This needs to be long enough to send the longest reasonable message, without being so long
    // as to effectively "hang" sending of mail.  The standard 30 second timeout isn't long enough
    // for pictures and the like.  For now, we'll use 15 minutes, in the knowledge that any socket
    // failure would probably generate an Exception before timing out anyway
    public static final int SEND_MAIL_TIMEOUT = (int)(15 * DateUtils.MINUTE_IN_MILLIS);

    protected EasOutboxService(Context _context, Mailbox _mailbox) {
        super(_context, _mailbox);
    }

    /**
     * Our own HttpEntity subclass that is able to insert opaque data (in this case the MIME
     * representation of the message body as stored in a temporary file) into the serializer stream
     */
    private static class SendMailEntity extends InputStreamEntity {
        private final Context mContext;
        private final FileInputStream mFileStream;
        private final long mFileLength;
        private final int mSendTag;
        private final Message mMessage;

        private static final int[] MODE_TAGS =  new int[] {Tags.COMPOSE_SEND_MAIL,
            Tags.COMPOSE_SMART_REPLY, Tags.COMPOSE_SMART_FORWARD};

        public SendMailEntity(Context context, FileInputStream instream, long length, int tag,
                Message message) {
            super(instream, length);
            mContext = context;
            mFileStream = instream;
            mFileLength = length;
            mSendTag = tag;
            mMessage = message;
        }

        /**
         * We always return -1 because we don't know the actual length of the POST data (this
         * causes HttpClient to send the data in "chunked" mode)
         */
        @Override
        public long getContentLength() {
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            try {
                // Calculate the overhead for the WBXML data
                writeTo(baos, false);
                // Return the actual size that will be sent
                return baos.size() + mFileLength;
            } catch (IOException e) {
                // Just return -1 (unknown)
            } finally {
                try {
                    baos.close();
                } catch (IOException e) {
                    // Ignore
                }
            }
            return -1;
        }

        @Override
        public void writeTo(OutputStream outstream) throws IOException {
            writeTo(outstream, true);
        }

        /**
         * Write the message to the output stream
         * @param outstream the output stream to write
         * @param withData whether or not the actual data is to be written; true when sending
         *   mail; false when calculating size only
         * @throws IOException
         */
        public void writeTo(OutputStream outstream, boolean withData) throws IOException {
            // Not sure if this is possible; the check is taken from the superclass
            if (outstream == null) {
                throw new IllegalArgumentException("Output stream may not be null");
            }

            // We'll serialize directly into the output stream
            Serializer s = new Serializer(outstream);
            // Send the appropriate initial tag
            s.start(mSendTag);
            // The Message-Id for this message (note that we cannot use the messageId stored in
            // the message, as EAS 14 limits the length to 40 chars and we use 70+)
            s.data(Tags.COMPOSE_CLIENT_ID, "SendMail-" + System.nanoTime());
            // We always save sent mail
            s.tag(Tags.COMPOSE_SAVE_IN_SENT_ITEMS);

            // If we're using smart reply/forward, we need info about the original message
            if (mSendTag != Tags.COMPOSE_SEND_MAIL) {
                OriginalMessageInfo info = getOriginalMessageInfo(mContext, mMessage.mId);
                if (info != null) {
                    s.start(Tags.COMPOSE_SOURCE);
                    // For search results, use the long id (stored in mProtocolSearchInfo); else,
                    // use folder id/item id combo
                    if (mMessage.mProtocolSearchInfo != null) {
                        s.data(Tags.COMPOSE_LONG_ID, mMessage.mProtocolSearchInfo);
                    } else {
                        s.data(Tags.COMPOSE_ITEM_ID, info.mItemId);
                        s.data(Tags.COMPOSE_FOLDER_ID, info.mCollectionId);
                    }
                    s.end();  // Tags.COMPOSE_SOURCE
                }
            }

            // Start the MIME tag; this is followed by "opaque" data (byte array)
            s.start(Tags.COMPOSE_MIME);
            // Send opaque data from the file stream
            if (withData) {
                s.opaque(mFileStream, (int)mFileLength);
            } else {
                s.opaqueWithoutData((int)mFileLength);
            }
            // And we're done
            s.end().end().done();
        }
    }

    private static class SendMailParser extends Parser {
        private final int mStartTag;
        private int mStatus;

        public SendMailParser(InputStream in, int startTag) throws IOException {
            super(in);
            mStartTag = startTag;
        }

        public int getStatus() {
            return mStatus;
        }

        /**
         * The only useful info in the SendMail response is the status; we capture and save it
         */
        @Override
        public boolean parse() throws IOException {
            if (nextTag(START_DOCUMENT) != mStartTag) {
                throw new IOException();
            }
            while (nextTag(START_DOCUMENT) != END_DOCUMENT) {
                if (tag == Tags.COMPOSE_STATUS) {
                    mStatus = getValueInt();
                } else {
                    skipTag();
                }
            }
            return true;
        }
    }

    /**
     * For OriginalMessageInfo, we use the terminology of EAS for the serverId and mailboxId of the
     * original message
     */
    protected static class OriginalMessageInfo {
        final long mRefId;
        final String mItemId;
        final String mCollectionId;

        OriginalMessageInfo(long refId, String itemId, String collectionId) {
            mRefId = refId;
            mItemId = itemId;
            mCollectionId = collectionId;
        }
    }

    /*package*/ String generateSmartSendCmd(boolean reply, OriginalMessageInfo info) {
        StringBuilder sb = new StringBuilder();
        sb.append(reply ? "SmartReply" : "SmartForward");
        sb.append("&ItemId=");
        sb.append(Uri.encode(info.mItemId, ":"));
        sb.append("&CollectionId=");
        sb.append(Uri.encode(info.mCollectionId, ":"));
        return sb.toString();
    }

    /**
     * Get information about the original message that is referenced by the message to be sent; this
     * information will exist for replies and forwards
     *
     * @param context the caller's context
     * @param msgId the id of the message we're sending
     * @return a data structure with the serverId and mailboxId of the original message, or null if
     * either or both of those pieces of information can't be found
     */
    private static OriginalMessageInfo getOriginalMessageInfo(Context context, long msgId) {
        // Note: itemId and collectionId are the terms used by EAS to refer to the serverId and
        // mailboxId of a Message
        String itemId = null;
        String collectionId = null;

        // First, we need to get the id of the reply/forward message
        String[] cols = Utility.getRowColumns(context, Body.CONTENT_URI,
                BODY_SOURCE_PROJECTION, WHERE_MESSAGE_KEY,
                new String[] {Long.toString(msgId)});
        long refId = 0;
        if (cols != null) {
            refId = Long.parseLong(cols[0]);
            // Then, we need the serverId and mailboxKey of the message
            cols = Utility.getRowColumns(context, Message.CONTENT_URI, refId,
                    SyncColumns.SERVER_ID, MessageColumns.MAILBOX_KEY,
                    MessageColumns.PROTOCOL_SEARCH_INFO);
            if (cols != null) {
                itemId = cols[0];
                long boxId = Long.parseLong(cols[1]);
                // Then, we need the serverId of the mailbox
                cols = Utility.getRowColumns(context, Mailbox.CONTENT_URI, boxId,
                        MailboxColumns.SERVER_ID);
                if (cols != null) {
                    collectionId = cols[0];
                }
            }
        }
        // We need either a longId or both itemId (serverId) and collectionId (mailboxId) to process
        // a smart reply or a smart forward
        if (itemId != null && collectionId != null){
            return new OriginalMessageInfo(refId, itemId, collectionId);
        }
        return null;
    }

    private void sendFailed(long msgId, int result) {
        ContentValues cv = new ContentValues();
        cv.put(SyncColumns.SERVER_ID, SEND_FAILED);
        Message.update(mContext, Message.CONTENT_URI, msgId, cv);
    }

    /**
     * See if a given attachment is among an array of attachments; it is if the locations of both
     * are the same (we're looking to see if they represent the same attachment on the server. Note
     * that an attachment that isn't on the server (e.g. an outbound attachment picked from the
     * gallery) won't have a location, so the result will always be false
     *
     * @param att the attachment to test
     * @param atts the array of attachments to look in
     * @return whether the test attachment is among the array of attachments
     */
    private static boolean amongAttachments(Attachment att, Attachment[] atts) {
        String location = att.mLocation;
        if (location == null) return false;
        for (Attachment a: atts) {
            if (location.equals(a.mLocation)) {
                return true;
            }
        }
        return false;
    }

    /**
     * Send a single message via EAS
     * Note that we mark messages SEND_FAILED when there is a permanent failure, rather than an
     * IOException, which is handled by ExchangeService with retries, backoffs, etc.
     *
     * @param cacheDir the cache directory for this context
     * @param msgId the _id of the message to send
     * @throws IOException
     */
    int sendMessage(File cacheDir, long msgId) throws IOException, MessagingException {
        // We always return SUCCESS unless the sending error is account-specific (security or
        // authentication) rather than message-specific; returning anything else will terminate
        // the Outbox sync! Message-specific errors are marked in the messages themselves.
        int result = EmailServiceStatus.SUCCESS;
        // Create a temporary file (this will hold the outgoing message in RFC822 (MIME) format)
        File tmpFile = File.createTempFile("eas_", "tmp", cacheDir);
        try {
            // Get the message and fail quickly if not found
            Message msg = Message.restoreMessageWithId(mContext, msgId);
            if (msg == null) return EmailServiceStatus.MESSAGE_NOT_FOUND;

            // See what kind of outgoing messge this is
            int flags = msg.mFlags;
            boolean reply = (flags & Message.FLAG_TYPE_REPLY) != 0;
            boolean forward = (flags & Message.FLAG_TYPE_FORWARD) != 0;
            boolean includeQuotedText = (flags & Message.FLAG_NOT_INCLUDE_QUOTED_TEXT) == 0;

            // The reference message and mailbox are called item and collection in EAS
            OriginalMessageInfo referenceInfo = null;
            // Respect the sense of the include quoted text flag
            if (includeQuotedText && (reply || forward)) {
                referenceInfo = getOriginalMessageInfo(mContext, msgId);
            }
            // Generally, we use SmartReply/SmartForward if we've got a good reference
            boolean smartSend = referenceInfo != null;
            // But we won't use SmartForward if the account isn't set up for it (currently, we only
            // use SmartForward for EAS 12.0 or later to avoid creating eml files that are
            // potentially difficult for the recipient to handle)
            if (forward && ((mAccount.mFlags & Account.FLAGS_SUPPORTS_SMART_FORWARD) == 0)) {
                smartSend = false;
            }

            ArrayList<Attachment> requiredAtts = null;
            if (smartSend && forward) {
                // See if we can really smart forward (all reference attachments must be sent)
                Attachment[] outAtts =
                        Attachment.restoreAttachmentsWithMessageId(mContext, msg.mId);
                Attachment[] refAtts =
                        Attachment.restoreAttachmentsWithMessageId(mContext, referenceInfo.mRefId);
                for (Attachment refAtt: refAtts) {
                    // If an original attachment isn't among what's going out, we can't be "smart"
                    if (!amongAttachments(refAtt, outAtts)) {
                        smartSend = false;
                        break;
                    }
                }
                if (smartSend) {
                    requiredAtts = new ArrayList<Attachment>();
                    for (Attachment outAtt: outAtts) {
                        // If an outgoing attachment isn't in original message, we must send it
                        if (!amongAttachments(outAtt, refAtts)) {
                            requiredAtts.add(outAtt);
                        }
                    }
                }
            }

            // Write the message to the temporary file
            FileOutputStream fileOutputStream = new FileOutputStream(tmpFile);
            // If we're using smartSend, send along our required attachments (which will be empty
            // if the user hasn't added new ones); otherwise, null to send everything in the msg
            Rfc822Output.writeTo(mContext, msg, fileOutputStream, smartSend, true,
                    smartSend ? requiredAtts : null);
            fileOutputStream.close();

            // Sending via EAS14 is a whole 'nother kettle of fish
            boolean isEas14 = (Double.parseDouble(mAccount.mProtocolVersion) >=
                Eas.SUPPORTED_PROTOCOL_EX2010_DOUBLE);

            while (true) {
                // Get an input stream to our temporary file and create an entity with it
                FileInputStream fileStream = new FileInputStream(tmpFile);
                long fileLength = tmpFile.length();

                // The type of entity depends on whether we're using EAS 14
                HttpEntity inputEntity;
                // For EAS 14, we need to save the wbxml tag we're using
                int modeTag = 0;
                if (isEas14) {
                    int mode =
                        !smartSend ? MODE_NORMAL : reply ? MODE_SMART_REPLY : MODE_SMART_FORWARD;
                    modeTag = SendMailEntity.MODE_TAGS[mode];
                    inputEntity =
                        new SendMailEntity(mContext, fileStream, fileLength, modeTag, msg);
                } else {
                    inputEntity = new InputStreamEntity(fileStream, fileLength);
                }
                // Create the appropriate command and POST it to the server
                String cmd = "SendMail";
                if (smartSend) {
                    // In EAS 14, we don't send itemId and collectionId in the command
                    if (isEas14) {
                        cmd = reply ? "SmartReply" : "SmartForward";
                    } else {
                        cmd = generateSmartSendCmd(reply, referenceInfo);
                    }
                }

                // If we're not EAS 14, add our save-in-sent setting here
                if (!isEas14) {
                    cmd += "&SaveInSent=T";
                }
                userLog("Send cmd: " + cmd);

                // Finally, post SendMail to the server
                EasResponse resp = sendHttpClientPost(cmd, inputEntity, SEND_MAIL_TIMEOUT);
                try {
                    fileStream.close();
                    int code = resp.getStatus();
                    if (code == HttpStatus.SC_OK) {
                        // HTTP OK before EAS 14 is a thumbs up; in EAS 14, we've got to parse
                        // the reply
                        if (isEas14) {
                            try {
                                // Try to parse the result
                                SendMailParser p =
                                    new SendMailParser(resp.getInputStream(), modeTag);
                                // If we get here, the SendMail failed; go figure
                                p.parse();
                                // The parser holds the status
                                int status = p.getStatus();
                                userLog("SendMail error, status: " + status);
                                if (CommandStatus.isNeedsProvisioning(status)) {
                                    result = EmailServiceStatus.SECURITY_FAILURE;
                                } else if (status == CommandStatus.ITEM_NOT_FOUND && smartSend) {
                                    // This is the retry case for EAS 14; we'll send without "smart"
                                    // commands next time
                                    resp.close();
                                    smartSend = false;
                                    continue;
                                }
                                sendFailed(msgId, result);
                                return result;
                            } catch (EmptyStreamException e) {
                                // This is actually fine; an empty stream means SendMail succeeded
                            }
                        }

                        // If we're here, the SendMail command succeeded
                        userLog("Deleting message...");
                        // Delete the message from the Outbox and send callback
                        mContentResolver.delete(
                                ContentUris.withAppendedId(Message.CONTENT_URI, msgId), null, null);
                        break;
                    } else if (code == EasSyncService.INTERNAL_SERVER_ERROR_CODE && smartSend) {
                        // This is the retry case for EAS 12.1 and below; we'll send without "smart"
                        // commands next time
                        resp.close();
                        smartSend = false;
                    } else {
                        userLog("Message sending failed, code: " + code);
                        if (resp.isAuthError()) {
                            result = EmailServiceStatus.LOGIN_FAILED;
                        } else if (resp.isProvisionError()) {
                            result = EmailServiceStatus.SECURITY_FAILURE;
                        }
                        sendFailed(msgId, result);
                        break;
                    }
                } finally {
                    resp.close();
                }
            }
        } finally {
            // Clean up the temporary file
            if (tmpFile.exists()) {
                tmpFile.delete();
            }
        }
        return result;
    }

    @Override
    public void run() {
        setupService();
        // Use SMTP flags for sending mail
        TrafficStats.setThreadStatsTag(TrafficFlags.getSmtpFlags(mContext, mAccount));
        File cacheDir = mContext.getCacheDir();
        try {
            mDeviceId = ExchangeService.getDeviceId(mContext);
            // Get a cursor to Outbox messages
            Cursor c = mContext.getContentResolver().query(Message.CONTENT_URI,
                    Message.ID_COLUMN_PROJECTION, MAILBOX_KEY_AND_NOT_SEND_FAILED,
                    new String[] {Long.toString(mMailbox.mId)}, null);
            try {
                // Loop through the messages, sending each one
                while (c.moveToNext()) {
                    long msgId = c.getLong(Message.ID_COLUMNS_ID_COLUMN);
                    if (msgId != 0) {
                        if (Utility.hasUnloadedAttachments(mContext, msgId)) {
                            // We'll just have to wait on this...
                            continue;
                        }
                        int result = sendMessage(cacheDir, msgId);
                        // If there's an error, it should stop the service; we will distinguish
                        // at least between login failures and everything else
                        if (result == EmailServiceStatus.LOGIN_FAILED) {
                            mExitStatus = EXIT_LOGIN_FAILURE;
                            return;
                        } else if (result == EmailServiceStatus.SECURITY_FAILURE) {
                            mExitStatus = EXIT_SECURITY_FAILURE;
                            return;
                        } else if (result == EmailServiceStatus.REMOTE_EXCEPTION) {
                            mExitStatus = EXIT_EXCEPTION;
                            return;
                        }
                    }
                }
            } finally {
                c.close();
            }
            mExitStatus = EXIT_DONE;
        } catch (IOException e) {
            mExitStatus = EXIT_IO_ERROR;
        } catch (Exception e) {
            userLog("Exception caught in EasOutboxService", e);
            mExitStatus = EXIT_EXCEPTION;
        } finally {
            userLog(mMailbox.mDisplayName, ": sync finished");
            userLog("Outbox exited with status ", mExitStatus);
            ExchangeService.done(this);
        }
    }

    /**
     * Convenience method for adding a Message to an account's outbox
     * @param context the context of the caller
     * @param accountId the accountId for the sending account
     * @param msg the message to send
     */
    public static void sendMessage(Context context, long accountId, Message msg) {
        Mailbox mailbox = Mailbox.restoreMailboxOfType(context, accountId, Mailbox.TYPE_OUTBOX);
        if (mailbox != null) {
            msg.mMailboxKey = mailbox.mId;
            msg.mAccountKey = accountId;
            msg.save(context);
        }
    }
}
