/*
 * 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 com.android.email.mail.MessagingException;
import com.android.email.mail.transport.Rfc822Output;
import com.android.email.provider.EmailContent.Body;
import com.android.email.provider.EmailContent.BodyColumns;
import com.android.email.provider.EmailContent.Mailbox;
import com.android.email.provider.EmailContent.MailboxColumns;
import com.android.email.provider.EmailContent.Message;
import com.android.email.provider.EmailContent.MessageColumns;
import com.android.email.provider.EmailContent.SyncColumns;

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

import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.os.RemoteException;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

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 = Body.MESSAGE_KEY + "=?";

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

    private void sendCallback(long msgId, String subject, int status) {
        try {
            SyncManager.callback().sendMessageStatus(msgId, subject, status, 0);
        } catch (RemoteException e) {
            // It's all good
        }
    }

    /**
     * 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 SyncManager 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 {
        int result;
        sendCallback(msgId, null, EmailServiceStatus.IN_PROGRESS);
        File tmpFile = File.createTempFile("eas_", "tmp", cacheDir);
        // Write the output to a temporary file
        try {
            String[] cols = getRowColumns(Message.CONTENT_URI, msgId, MessageColumns.FLAGS,
                    MessageColumns.SUBJECT);
            int flags = Integer.parseInt(cols[0]);
            String subject = cols[1];

            boolean reply = (flags & Message.FLAG_TYPE_REPLY) != 0;
            boolean forward = (flags & Message.FLAG_TYPE_FORWARD) != 0;
            // The reference message and mailbox are called item and collection in EAS
            String itemId = null;
            String collectionId = null;
            if (reply || forward) {
                // First, we need to get the id of the reply/forward message
                cols = getRowColumns(Body.CONTENT_URI, BODY_SOURCE_PROJECTION,
                        WHERE_MESSAGE_KEY, new String[] {Long.toString(msgId)});
                if (cols != null) {
                    long refId = Long.parseLong(cols[0]);
                    // Then, we need the serverId and mailboxKey of the message
                    cols = getRowColumns(Message.CONTENT_URI, refId, SyncColumns.SERVER_ID,
                            MessageColumns.MAILBOX_KEY);
                    if (cols != null) {
                        itemId = cols[0];
                        long boxId = Long.parseLong(cols[1]);
                        // Then, we need the serverId of the mailbox
                        cols = getRowColumns(Mailbox.CONTENT_URI, boxId, MailboxColumns.SERVER_ID);
                        if (cols != null) {
                            collectionId = cols[0];
                        }
                    }
                }
            }

            boolean smartSend = itemId != null && collectionId != null;

            // Write the message in rfc822 format to the temporary file
            FileOutputStream fileStream = new FileOutputStream(tmpFile);
            Rfc822Output.writeTo(mContext, msgId, fileStream, !smartSend, true);
            fileStream.close();

            // Now, get an input stream to our temporary file and create an entity with it
            FileInputStream inputStream = new FileInputStream(tmpFile);
            InputStreamEntity inputEntity =
                new InputStreamEntity(inputStream, tmpFile.length());

            // Create the appropriate command and POST it to the server
            String cmd = "SendMail&SaveInSent=T";
            if (smartSend) {
                cmd = reply ? "SmartReply" : "SmartForward";
                cmd += "&ItemId=" + itemId + "&CollectionId=" + collectionId + "&SaveInSent=T";
            }
            userLog("Send cmd: " + cmd);
            HttpResponse resp = sendHttpClientPost(cmd, inputEntity);

            inputStream.close();
            int code = resp.getStatusLine().getStatusCode();
            if (code == HttpStatus.SC_OK) {
                userLog("Deleting message...");
                mContentResolver.delete(ContentUris.withAppendedId(Message.CONTENT_URI, msgId),
                        null, null);
                result = EmailServiceStatus.SUCCESS;
                sendCallback(-1, subject, EmailServiceStatus.SUCCESS);
            } else {
                userLog("Message sending failed, code: " + code);
                ContentValues cv = new ContentValues();
                cv.put(SyncColumns.SERVER_ID, SEND_FAILED);
                Message.update(mContext, Message.CONTENT_URI, msgId, cv);
                result = EmailServiceStatus.REMOTE_EXCEPTION;
                if (isAuthError(code)) {
                    result = EmailServiceStatus.LOGIN_FAILED;
                }
                sendCallback(msgId, null, result);

            }
        } catch (IOException e) {
            // We catch this just to send the callback
            sendCallback(msgId, null, EmailServiceStatus.CONNECTION_ERROR);
            throw e;
        } finally {
            // Clean up the temporary file
            if (tmpFile.exists()) {
                tmpFile.delete();
            }
        }
        return result;
    }

    @Override
    public void run() {
        setupService();

        File cacheDir = mContext.getCacheDir();
        try {
            mDeviceId = SyncManager.getDeviceId();
            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 {
                while (c.moveToNext()) {
                    long msgId = c.getLong(0);
                    if (msgId != 0) {
                        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.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);
            SyncManager.done(this);
        }
    }
}