/*
 * 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.AuthenticationFailedException;
import com.android.email.mail.MessagingException;
import com.android.exchange.EmailContent.Account;
import com.android.exchange.EmailContent.Attachment;
import com.android.exchange.EmailContent.AttachmentColumns;
import com.android.exchange.EmailContent.HostAuth;
import com.android.exchange.EmailContent.Mailbox;
import com.android.exchange.EmailContent.MailboxColumns;
import com.android.exchange.EmailContent.Message;
import com.android.exchange.adapter.EasContactsSyncAdapter;
import com.android.exchange.adapter.EasEmailSyncAdapter;
import com.android.exchange.adapter.EasFolderSyncParser;
import com.android.exchange.adapter.EasPingParser;
import com.android.exchange.adapter.EasSerializer;
import com.android.exchange.adapter.EasSyncAdapter;
import com.android.exchange.adapter.EasParser.EasParserException;
import com.android.exchange.utility.Base64;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.AllowAllHostnameVerifier;
import org.apache.http.impl.client.DefaultHttpClient;

import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.os.RemoteException;
import android.util.Log;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.ProtocolException;
import java.net.URI;
import java.net.URL;
import java.net.URLEncoder;
import java.util.ArrayList;

import javax.net.ssl.HttpsURLConnection;

public class EasSyncService extends InteractiveSyncService {

    private static final String WINDOW_SIZE = "10";
    private static final String WHERE_ACCOUNT_KEY_AND_SERVER_ID =
        MailboxColumns.ACCOUNT_KEY + "=? and " + MailboxColumns.SERVER_ID + "=?";
    private static final String WHERE_SYNC_FREQUENCY_PING =
        Mailbox.SYNC_FREQUENCY + '=' + Account.CHECK_INTERVAL_PING;
    private static final String AND_FREQUENCY_PING_PUSH_AND_NOT_ACCOUNT_MAILBOX = " AND " +
        MailboxColumns.SYNC_FREQUENCY + " IN (" + Account.CHECK_INTERVAL_PING +
        ',' + Account.CHECK_INTERVAL_PUSH + ") AND " + MailboxColumns.SERVER_ID + "!=\"" +
        Eas.ACCOUNT_MAILBOX + '\"';
    
    static private final int CHUNK_SIZE = 16 * 1024;

    // Reasonable default
    String mProtocolVersion = "2.5";
    public Double mProtocolVersionDouble;
    static String mDeviceId = null;
    static String mDeviceType = "Android";
    EasSyncAdapter mTarget;
    String mAuthString = null;
    String mCmdString = null;
    String mVersions;
    public String mHostAddress;
    public String mUserName;
    public String mPassword;
    String mDomain = null;
    boolean mSentCommands;
    boolean mIsIdle = false;
    boolean mSsl = true;
    public Context mContext;
    public ContentResolver mContentResolver;
    String[] mBindArguments = new String[2];
    InputStream mPendingPartInputStream = null;
    private boolean mStop = false;
    private Object mWaitTarget = new Object();

    public EasSyncService(Context _context, Mailbox _mailbox) {
        super(_context, _mailbox);
        mContext = _context;
        mContentResolver = _context.getContentResolver();
        HostAuth ha = HostAuth.restoreHostAuthWithId(_context, mAccount.mHostAuthKeyRecv);
        mSsl = (ha.mFlags & HostAuth.FLAG_SSL) != 0;
    }

    private EasSyncService(String prefix) {
        super(prefix);
    }

    public EasSyncService() {
        this("EAS Validation");
    }

    @Override
    public void ping() {
        userLog("We've been pinged!");
        synchronized (mWaitTarget) {
            mWaitTarget.notify();
        }
    }

    @Override
    public void stop() {
        mStop = true;
    }

    public int getSyncStatus() {
        return 0;
    }

    /* (non-Javadoc)
     * @see com.android.exchange.SyncService#validateAccount(java.lang.String, java.lang.String, java.lang.String, int, boolean, android.content.Context)
     */
    public void validateAccount(String hostAddress, String userName, String password, int port,
            boolean ssl, Context context) throws MessagingException {
        try {
            if (Eas.USER_DEBUG) {
                userLog("Testing EAS: " + hostAddress + ", " + userName + ", ssl = " + ssl);
            }
            EasSerializer s = new EasSerializer();
            s.start("FolderSync").start("FolderSyncKey").text("0").end("FolderSyncKey")
                .end("FolderSync").end();
            EasSyncService svc = new EasSyncService("%TestAccount%");
            svc.mHostAddress = hostAddress;
            svc.mUserName = userName;
            svc.mPassword = password;
            svc.mSsl = ssl;
            HttpURLConnection uc = svc.sendEASPostCommand("FolderSync", s.toString());
            int code = uc.getResponseCode();
            userLog("Validation response code: " + code);
            if (code == HttpURLConnection.HTTP_OK) {
                // No exception means successful validation
                userLog("Validation successful");
                return;
            }
            if (code == HttpURLConnection.HTTP_UNAUTHORIZED ||
                    code == HttpURLConnection.HTTP_FORBIDDEN) {
                userLog("Authentication failed");
                throw new AuthenticationFailedException("Validation failed");
            } else {
                // TODO Need to catch other kinds of errors (e.g. policy) For now, report the code.
                userLog("Validation failed, reporting I/O error: " + code);
                throw new MessagingException(MessagingException.IOERROR);
            }
        } catch (IOException e) {
            userLog("IOException caught, reporting I/O error: " + e.getMessage());
            throw new MessagingException(MessagingException.IOERROR);
        }

    }


    @Override
    public void loadAttachment(Attachment att, IEmailServiceCallback cb) {
        // TODO Auto-generated method stub
    }

    @Override
    public void reloadFolderList() {
        // TODO Auto-generated method stub
    }

    @Override
    public void startSync() {
        // TODO Auto-generated method stub
    }

    @Override
    public void stopSync() {
        // TODO Auto-generated method stub
    }

    protected HttpURLConnection sendEASPostCommand(String cmd, String data) throws IOException {
        HttpURLConnection uc = setupEASCommand("POST", cmd);
        if (uc != null) {
            uc.setRequestProperty("Content-Length", Integer.toString(data.length() + 2));
            OutputStreamWriter w = new OutputStreamWriter(uc.getOutputStream(), "UTF-8");
            w.write(data);
            w.write("\r\n");
            w.flush();
            w.close();
        }
        return uc;
    }

    private void doStatusCallback(IEmailServiceCallback callback, long messageId,
            long attachmentId, int status) {
        try {
            callback.status(messageId, attachmentId, status, 0);
        } catch (RemoteException e2) {
            // No danger if the client is no longer around
        }
    }

    private void doProgressCallback(IEmailServiceCallback callback, long messageId,
            long attachmentId, int progress) {
        try {
            callback.status(messageId, attachmentId, EmailServiceStatus.IN_PROGRESS, progress);
        } catch (RemoteException e2) {
            // No danger if the client is no longer around
        }
    }

    /**
     * Loads an attachment, based on the PartRequest passed in.  The PartRequest is basically our
     * wrapper for Attachment
     * @param req the part (attachment) to be retrieved
     * @param external whether the attachment should be loaded to external storage
     * @throws IOException
     */
    protected void getAttachment(PartRequest req, boolean external) throws IOException {
        // TODO Implement internal storage as required
        IEmailServiceCallback callback = req.callback;
        Attachment att = req.att;
        Message msg = Message.restoreMessageWithId(mContext, att.mMessageKey);
        doProgressCallback(callback, msg.mId, att.mId, 0);
        DefaultHttpClient client = new DefaultHttpClient();
        String us = makeUriString("GetAttachment", "&AttachmentName=" + att.mLocation);
        HttpPost method = new HttpPost(URI.create(us));
        method.setHeader("Authorization", mAuthString);

        HttpResponse res = client.execute(method);
        int status = res.getStatusLine().getStatusCode();
        if (status == HttpURLConnection.HTTP_OK) {
            HttpEntity e = res.getEntity();
            int len = (int)e.getContentLength();
            String type = e.getContentType().getValue();
            if (Eas.TEST_DEBUG) {
                Log.v(TAG, "Attachment code: " + status + ", Length: " + len + ", Type: " + type);
            }
            InputStream is = res.getEntity().getContent();
            File f = Attachment.createUniqueFile(att.mFileName);
            if (f != null) {
                FileOutputStream os = new FileOutputStream(f);
                if (len > 0) {
                    try {
                        mPendingPartRequest = req;
                        mPendingPartInputStream = is;
                        byte[] bytes = new byte[CHUNK_SIZE];
                        int length = len;
                        while (len > 0) {
                            int n = (len > CHUNK_SIZE ? CHUNK_SIZE : len);
                            int read = is.read(bytes, 0, n);
                            os.write(bytes, 0, read);
                            len -= read;
                            int pct = ((length - len) * 100 / length);
                            doProgressCallback(callback, msg.mId, att.mId, pct);
                        }
                    } finally {
                        mPendingPartRequest = null;
                        mPendingPartInputStream = null;
                    }
                }
                os.flush();
                os.close();

                // EmailProvider will throw an exception if we try to update an unsaved attachment
                if (att.isSaved()) {
                    ContentValues cv = new ContentValues();
                    cv.put(AttachmentColumns.CONTENT_URI, f.getAbsolutePath());
                    cv.put(AttachmentColumns.MIME_TYPE, type);
                    att.update(mContext, cv);
                    doStatusCallback(callback, msg.mId, att.mId, EmailServiceStatus.SUCCESS);
                }
            }
        } else {
            doStatusCallback(callback, msg.mId, att.mId, EmailServiceStatus.MESSAGE_NOT_FOUND);
        }
    }

    private HttpURLConnection setupEASCommand(String method, String cmd) throws IOException {
        return setupEASCommand(method, cmd, null);
    }

    private String makeUriString(String cmd, String extra) {
         // Cache the authentication string and the command string
        if (mDeviceId == null)
            mDeviceId = "droidfu";
        String safeUserName = URLEncoder.encode(mUserName);
        if (mAuthString == null) {
            String cs = mUserName + ':' + mPassword;
            mAuthString = "Basic " + Base64.encodeBytes(cs.getBytes());
            mCmdString = "&User=" + safeUserName + "&DeviceId=" + mDeviceId + "&DeviceType="
                    + mDeviceType;
        }

        String us = (mSsl ? "https" : "http") + "://" + mHostAddress +
            "/Microsoft-Server-ActiveSync";
        if (cmd != null) {
            us += "?Cmd=" + cmd + mCmdString;
        }
        if (extra != null) {
            us += extra;
        }
        return us;
    }

    private HttpURLConnection setupEASCommand(String method, String cmd, String extra) 
            throws IOException {
        try {
            String us = makeUriString(cmd, extra);
            URL u = new URL(us);
            HttpURLConnection uc = (HttpURLConnection)u.openConnection();
            HttpURLConnection.setFollowRedirects(true);
 
            if (mSsl) {
                ((HttpsURLConnection)uc).setHostnameVerifier(new AllowAllHostnameVerifier());
            }

            uc.setConnectTimeout(10 * SECS);
            uc.setReadTimeout(20 * MINS);
            if (method.equals("POST")) {
                uc.setDoOutput(true);
            }
            uc.setRequestMethod(method);
            uc.setRequestProperty("Authorization", mAuthString);

            if (extra == null) {
                if (cmd != null && cmd.startsWith("SendMail&")) {
                    uc.setRequestProperty("Content-Type", "message/rfc822");
                } else {
                    uc.setRequestProperty("Content-Type", "application/vnd.ms-sync.wbxml");
                }
                uc.setRequestProperty("MS-ASProtocolVersion", mProtocolVersion);
                uc.setRequestProperty("Connection", "keep-alive");
                uc.setRequestProperty("User-Agent", mDeviceType + '/' + Eas.VERSION);
            } else {
                uc.setRequestProperty("Content-Length", "0");
            }

            return uc;
        } catch (MalformedURLException e) {
            // TODO See if there is a better exception to throw here and below
            throw new IOException();
        } catch (ProtocolException e) {
            throw new IOException();
        }
    }

    String getTargetCollectionClassFromCursor(Cursor c) {
        int type = c.getInt(Mailbox.CONTENT_TYPE_COLUMN);
        if (type == Mailbox.TYPE_CONTACTS) {
            return "Contacts";
        } else if (type == Mailbox.TYPE_CALENDAR) {
            return "Calendar";
        } else {
            return "Email";
        }
    }

    /**
     * Performs FolderSync
     *
     * @throws IOException
     * @throws EasParserException
     */
    public void runMain() throws IOException, EasParserException {
        try {
            if (mAccount.mSyncKey == null) {
                mAccount.mSyncKey = "0";
                userLog("Account syncKey RESET");
                mAccount.saveOrUpdate(mContext);
            }

            // When we first start up, change all ping mailboxes to push.
            ContentValues cv = new ContentValues();
            cv.put(Mailbox.SYNC_FREQUENCY, Account.CHECK_INTERVAL_PUSH);
            if (mContentResolver.update(Mailbox.CONTENT_URI, cv,
                    WHERE_SYNC_FREQUENCY_PING, null) > 0) {
                SyncManager.kick();
            }

            userLog("Account syncKey: " + mAccount.mSyncKey);
            HttpURLConnection uc = setupEASCommand("OPTIONS", null);
            if (uc != null) {
                int code = uc.getResponseCode();
                userLog("OPTIONS response: " + code);
                if (code == HttpURLConnection.HTTP_OK) {
                    mVersions = uc.getHeaderField("ms-asprotocolversions");
                    if (mVersions != null) {
                        if (mVersions.contains("12.0")) {
                            mProtocolVersion = "12.0";
                        }
                        mProtocolVersionDouble = Double.parseDouble(mProtocolVersion);
                        mAccount.mProtocolVersion = mProtocolVersion;
                        userLog(mVersions);
                        userLog("Using version " + mProtocolVersion);
                    } else {
                        throw new IOException();
                    }

                    while (!mStop) {
                        EasSerializer s = new EasSerializer();
                        s.start("FolderSync").start("FolderSyncKey").text(mAccount.mSyncKey).end(
                                "FolderSyncKey").end("FolderSync").end();
                        uc = sendEASPostCommand("FolderSync", s.toString());
                        code = uc.getResponseCode();
                        if (code == HttpURLConnection.HTTP_OK) {
                            String encoding = uc.getHeaderField("Transfer-Encoding");
                            if (encoding == null) {
                                int len = uc.getHeaderFieldInt("Content-Length", 0);
                                if (len > 0) {
                                    InputStream is = uc.getInputStream();
                                    // Returns true if we need to sync again
                                    if (new EasFolderSyncParser(is, this).parse()) {
                                        continue;
                                    }
                                }
                            } else if (encoding.equalsIgnoreCase("chunked")) {
                                // TODO We don't handle this yet
                            }
                        } else {
                            userLog("FolderSync response error: " + code);
                        }

                        // Wait for push notifications.
                        String threadName = Thread.currentThread().getName();
                        try {
                            runPingLoop();
                        } catch (StaleFolderListException e) {
                            // We break out if we get told about a stale folder list
                            userLog("Ping interrupted; folder list requires sync...");
                        } finally {
                            Thread.currentThread().setName(threadName);
                        }
                    }
                 }
            }
        } catch (MalformedURLException e) {
            throw new IOException();
        }
    }

    void runPingLoop() throws IOException, StaleFolderListException {
        // Do push for all sync services here
        long endTime = System.currentTimeMillis() + (30*MINS);

        while (System.currentTimeMillis() < endTime) {
            // Count of pushable mailboxes
            int pushCount = 0;
            // Count of mailboxes that can be pushed right now
            int canPushCount = 0;
            EasSerializer s = new EasSerializer();
            HttpURLConnection uc;
            int code;
            Cursor c = mContentResolver.query(Mailbox.CONTENT_URI, Mailbox.CONTENT_PROJECTION,
                    MailboxColumns.ACCOUNT_KEY + '=' + mAccount.mId +
                    AND_FREQUENCY_PING_PUSH_AND_NOT_ACCOUNT_MAILBOX, null, null);

            try {
                // Loop through our pushed boxes seeing what is available to push
                while (c.moveToNext()) {
                    pushCount++;
                    // Two requirements for push:
                    // 1) SyncManager tells us the mailbox is syncable (not running, not stopped)
                    // 2) The syncKey isn't "0" (i.e. it's synced at least once)
                    if (SyncManager.canSync(c.getLong(Mailbox.CONTENT_ID_COLUMN))) {
                        String syncKey = c.getString(Mailbox.CONTENT_SYNC_KEY_COLUMN);
                        if (syncKey == null || syncKey.equals("0")) {
                            continue;
                        }
                        if (canPushCount++ == 0) {
                            // Initialize the Ping command
                            s.start("Ping").data("HeartbeatInterval", "900").start("PingFolders");
                        }
                        // When we're ready for Calendar/Contacts, we will check folder type
                        // TODO Save Calendar and Contacts!! Mark as not visible!
                        String folderClass = getTargetCollectionClassFromCursor(c);
                        s.start("PingFolder")
                            .data("PingId", c.getString(Mailbox.CONTENT_SERVER_ID_COLUMN))
                            .data("PingClass", folderClass)
                            .end("PingFolder");
                        userLog("Ping ready for: " + folderClass + ", " +
                                c.getString(Mailbox.CONTENT_SERVER_ID_COLUMN) + " (" +
                                c.getString(Mailbox.CONTENT_DISPLAY_NAME_COLUMN) + ')');
                    } else {
                        userLog(c.getString(Mailbox.CONTENT_DISPLAY_NAME_COLUMN) +
                                " not ready for ping");
                    }
                }
            } finally {
                c.close();
            }

            if (canPushCount > 0 && (canPushCount == pushCount)) {
                // If we have some number that are ready for push, send Ping to the server
                s.end("PingFolders").end("Ping").end();
                uc = sendEASPostCommand("Ping", s.toString());
                Thread.currentThread().setName(mAccount.mDisplayName + ": Ping");
                userLog("Sending ping, timeout: " + uc.getReadTimeout() / 1000 + "s");
                code = uc.getResponseCode();
                userLog("Ping response: " + code);
                if (code == HttpURLConnection.HTTP_OK) {
                    String encoding = uc.getHeaderField("Transfer-Encoding");
                    if (encoding == null) {
                        int len = uc.getHeaderFieldInt("Content-Length", 0);
                        if (len > 0) {
                            parsePingResult(uc, mContentResolver);
                        } else {
                            // This implies a connection issue that we can't handle
                            throw new IOException();
                        }
                    } else {
                        // It shouldn't be possible for EAS server to send chunked data here
                        throw new IOException();
                    }
                } else if (code == HttpURLConnection.HTTP_UNAUTHORIZED ||
                        code == HttpURLConnection.HTTP_FORBIDDEN) {
                    mExitStatus = AbstractSyncService.EXIT_LOGIN_FAILURE;
                    userLog("Authorization error during Ping: " + code);
                    throw new IOException();
                }
            } else if (pushCount > 0) {
                // If we want to Ping, but can't just yet, wait 10 seconds and try again
                userLog("pingLoop waiting for " + (pushCount - canPushCount) + " box(es)");
                sleep(10*SECS);
            } else {
                // We've got nothing to do, so let's hang out for a while
                sleep(10*MINS);
            }
        }
    }

    void sleep(long ms) {
        try {
            Thread.sleep(ms);
        } catch (InterruptedException e) {
            // Doesn't matter whether we stop early; it's the thought that counts
        }
    }

    void parsePingResult(HttpURLConnection uc, ContentResolver cr)
        throws IOException, StaleFolderListException {
        EasPingParser pp = new EasPingParser(uc.getInputStream(), this);
        if (pp.parse()) {
            // True indicates some mailboxes need syncing...
            // syncList has the serverId's of the mailboxes...
            mBindArguments[0] = Long.toString(mAccount.mId);
            ArrayList<String> syncList = pp.getSyncList();
            for (String serverId: syncList) {
                mBindArguments[1] = serverId;
                Cursor c = cr.query(Mailbox.CONTENT_URI, Mailbox.CONTENT_PROJECTION,
                        WHERE_ACCOUNT_KEY_AND_SERVER_ID, mBindArguments, null);
                try {
                    if (c.moveToFirst()) {
                        SyncManager.startManualSync(c.getLong(Mailbox.CONTENT_ID_COLUMN), null);
                    }
                } finally {
                    c.close();
                }
            }
        }
    }

    ByteArrayInputStream readResponse(HttpURLConnection uc) throws IOException {
        String encoding = uc.getHeaderField("Transfer-Encoding");
        if (encoding == null) {
            int len = uc.getHeaderFieldInt("Content-Length", 0);
            if (len > 0) {
                InputStream in = uc.getInputStream();
                byte[] bytes = new byte[len];
                int remain = len;
                int offs = 0;
                while (remain > 0) {
                    int read = in.read(bytes, offs, remain);
                    remain -= read;
                    offs += read;
                }
                return new ByteArrayInputStream(bytes);
            }
        } else if (encoding.equalsIgnoreCase("chunked")) {
            // TODO We don't handle this yet
            return null;
        }
        return null;
    }

    String readResponseString(HttpURLConnection uc) throws IOException {
        String encoding = uc.getHeaderField("Transfer-Encoding");
        if (encoding == null) {
            int len = uc.getHeaderFieldInt("Content-Length", 0);
            if (len > 0) {
                InputStream in = uc.getInputStream();
                byte[] bytes = new byte[len];
                int remain = len;
                int offs = 0;
                while (remain > 0) {
                    int read = in.read(bytes, offs, remain);
                    remain -= read;
                    offs += read;
                }
                return new String(bytes);
            }
        } else if (encoding.equalsIgnoreCase("chunked")) {
            // TODO We don't handle this yet
            return null;
        }
        return null;
    }

    /**
     * EAS requires a unique device id, so that sync is possible from a variety of different
     * devices (e.g. the syncKey is specific to a device)  If we're on an emulator or some other
     * device that doesn't provide one, we can create it as droid<n> where <n> is system time.
     * This would work on a real device as well, but it would be better to use the "real" id if
     * it's available
     */
    private String getSimulatedDeviceId() {
        try {
            File f = mContext.getFileStreamPath("deviceName");
            BufferedReader rdr = null;
            String id;
            if (f.exists() && f.canRead()) {
                rdr = new BufferedReader(new FileReader(f));
                id = rdr.readLine();
                rdr.close();
                return id;
            } else if (f.createNewFile()) {
                BufferedWriter w = new BufferedWriter(new FileWriter(f));
                id = "droid" + System.currentTimeMillis();
                w.write(id);
                w.close();
            }
        } catch (FileNotFoundException e) {
            // We'll just use the default below
        } catch (IOException e) {
            // We'll just use the default below
        }
        return "droid0";
    }

    /**
     * Common code to sync E+PIM data
     *
     * @param target, an EasMailbox, EasContacts, or EasCalendar object
     */
    public void sync(EasSyncAdapter target) throws IOException {
        mTarget = target;
        Mailbox mailbox = target.mMailbox;

        boolean moreAvailable = true;
        while (!mStop && moreAvailable) {
            runAwake();
            waitForConnectivity();

            while (true) {
                PartRequest req = null;
                synchronized (mPartRequests) {
                    if (mPartRequests.isEmpty()) {
                        break;
                    } else {
                        req = mPartRequests.get(0);
                    }
                }
                getAttachment(req, true);
                synchronized(mPartRequests) {
                    mPartRequests.remove(req);
                }
            }

            EasSerializer s = new EasSerializer();
            if (mailbox.mSyncKey == null) {
                userLog("Mailbox syncKey RESET");
                mailbox.mSyncKey = "0";
                mailbox.mSyncFrequency = Account.CHECK_INTERVAL_PUSH;
            }
            String className = target.getCollectionName();
            userLog("Sending " + className + " syncKey: " + mailbox.mSyncKey);
            s.start("Sync")
                .start("Collections")
                .start("Collection")
                .data("Class", className)
                .data("SyncKey", mailbox.mSyncKey)
                .data("CollectionId", mailbox.mServerId)
                .tag("DeletesAsMoves");

            // EAS doesn't like GetChanges if the syncKey is "0"; not documented
            if (!mailbox.mSyncKey.equals("0")) {
                s.tag("GetChanges");
            }
            s.data("WindowSize", WINDOW_SIZE);
            boolean options = false;
            if (!className.equals("Contacts")) {
                // Set the lookback appropriately (EAS calls this a "filter")
                String filter = Eas.FILTER_1_WEEK;
                switch (mAccount.mSyncLookback) {
                    case com.android.email.Account.SYNC_WINDOW_1_DAY: {
                        filter = Eas.FILTER_1_DAY;
                        break;
                    }
                    case com.android.email.Account.SYNC_WINDOW_3_DAYS: {
                        filter = Eas.FILTER_3_DAYS;
                        break;
                    }
                    case com.android.email.Account.SYNC_WINDOW_1_WEEK: {
                        filter = Eas.FILTER_1_WEEK;
                        break;
                    }
                    case com.android.email.Account.SYNC_WINDOW_2_WEEKS: {
                        filter = Eas.FILTER_2_WEEKS;
                        break;
                    }
                    case com.android.email.Account.SYNC_WINDOW_1_MONTH: {
                        filter = Eas.FILTER_1_MONTH;
                        break;
                    }
                    case com.android.email.Account.SYNC_WINDOW_ALL: {
                        filter = Eas.FILTER_ALL;
                        break;
                    }
                }
                s.start("Options").data("FilterType", filter);
                if (mProtocolVersionDouble < 12.0) {
                    s.data("Truncation", "7");
                }
                options = true;
            }
            if (mProtocolVersionDouble >= 12.0) {
                if (!options) {
                    options = true;
                    s.start("Options");
                }
                s.start("BodyPreference")
                    .data("BodyPreferenceType", Eas.BODY_PREFERENCE_HTML)
                    .data("BodyPreferenceTruncationSize", Eas.DEFAULT_BODY_TRUNCATION_SIZE)
                    .end("BodyPreference");
            }
            if (options) {
                s.end("Options");
            }

            // Send our changes up to the server
            target.sendLocalChanges(s, this);

            s.end("Collection").end("Collections").end("Sync").end();
            HttpURLConnection uc = sendEASPostCommand("Sync", s.toString());
            int code = uc.getResponseCode();
            if (code == HttpURLConnection.HTTP_OK) {
                ByteArrayInputStream is = readResponse(uc);
                if (is != null) {
                    moreAvailable = target.parse(is, this);
                    target.cleanup(this);
                }
            } else {
                userLog("Sync response error: " + code);
                if (code == HttpURLConnection.HTTP_UNAUTHORIZED ||
                        code == HttpURLConnection.HTTP_FORBIDDEN) {
                    mExitStatus = AbstractSyncService.EXIT_LOGIN_FAILURE;
                }
                return;
            }
        }
    }

    /* (non-Javadoc)
     * @see java.lang.Runnable#run()
     */
    public void run() {
        mThread = Thread.currentThread();
        TAG = mThread.getName();
        mDeviceId = android.provider.Settings.Secure.getString(mContext.getContentResolver(),
                android.provider.Settings.Secure.ANDROID_ID);
        // Generate a device id if we don't have one
        if (mDeviceId == null) {
            mDeviceId = getSimulatedDeviceId();
        }
        HostAuth ha = HostAuth.restoreHostAuthWithId(mContext, mAccount.mHostAuthKeyRecv);
        mHostAddress = ha.mAddress;
        mUserName = ha.mLogin;
        mPassword = ha.mPassword;

        // Make sure account and mailbox are always the latest from the database
        mAccount = Account.restoreAccountWithId(mContext, mAccount.mId);
        mMailbox = Mailbox.restoreMailboxWithId(mContext, mMailbox.mId);
        try {
            if (mMailbox.mServerId.equals(Eas.ACCOUNT_MAILBOX)) {
                runMain();
            } else {
                EasSyncAdapter target;
                mAccount = Account.restoreAccountWithId(mContext, mAccount.mId);
                mProtocolVersion = mAccount.mProtocolVersion;
                mProtocolVersionDouble = Double.parseDouble(mProtocolVersion);
                if (mMailbox.mType == Mailbox.TYPE_CONTACTS)
                    target = new EasContactsSyncAdapter(mMailbox);
                else {
                    target = new EasEmailSyncAdapter(mMailbox);
                }
                // We loop here because someone might have put a request in while we were syncing
                // and we've missed that opportunity...
                do {
                    if (mRequestTime != 0) {
                        userLog("Looping for user request...");
                        mRequestTime = 0;
                    }
                    sync(target);
                } while (mRequestTime != 0);
            }
            mExitStatus = EXIT_DONE;
        } catch (IOException e) {
            userLog("Caught IOException");
            mExitStatus = EXIT_IO_ERROR;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            userLog(mMailbox.mDisplayName + ": sync finished");
            SyncManager.done(this);
        }
    }
}
