/*
 *  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.BroadcastReceiver;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.util.Log;

import com.android.emailcommon.provider.EmailContent.Message;
import com.android.emailcommon.provider.EmailContent.MessageColumns;
import com.android.emailcommon.provider.ProviderUnavailableException;

import java.util.ArrayList;

/**
 * EmailSyncAlarmReceiver (USAR) is used by the SyncManager to start up-syncs of user-modified data
 * back to the Exchange server.
 *
 * Here's how this works for Email, for example:
 *
 * 1) User modifies or deletes an email from the UI.
 * 2) SyncManager, which has a ContentObserver watching the Message class, is alerted to a change
 * 3) SyncManager sets an alarm (to be received by USAR) for a few seconds in the
 * future (currently 15), the delay preventing excess syncing (think of it as a debounce mechanism).
 * 4) ESAR Receiver's onReceive method is called
 * 5) ESAR goes through all change and deletion records and compiles a list of mailboxes which have
 * changes to be uploaded.
 * 6) ESAR calls SyncManager to start syncs of those mailboxes
 *
 */
public class EmailSyncAlarmReceiver extends BroadcastReceiver {
    final String[] MAILBOX_DATA_PROJECTION = {MessageColumns.MAILBOX_KEY};

    @Override
    public void onReceive(final Context context, Intent intent) {
        new Thread(new Runnable() {
            public void run() {
                handleReceive(context);
            }
        }).start();
    }

    private void handleReceive(Context context) {
        ArrayList<Long> mailboxesToNotify = new ArrayList<Long>();
        ContentResolver cr = context.getContentResolver();
        int messageCount = 0;
        
        // Get a selector for EAS accounts (we don't want to sync on changes to POP/IMAP messages)
        String selector = ExchangeService.getEasAccountSelector();
        
        try {
            // Find all of the deletions
            Cursor c = cr.query(Message.DELETED_CONTENT_URI, MAILBOX_DATA_PROJECTION, selector,
                   null, null);
            try {
                // Keep track of which mailboxes to notify; we'll only notify each one once
                while (c.moveToNext()) {
                    messageCount++;
                    long mailboxId = c.getLong(0);
                    if (!mailboxesToNotify.contains(mailboxId)) {
                        mailboxesToNotify.add(mailboxId);
                    }
                }
            } finally {
                c.close();
            }

            // Now, find changed messages
            c = cr.query(Message.UPDATED_CONTENT_URI, MAILBOX_DATA_PROJECTION, selector,
                    null, null);
            try {
                // Keep track of which mailboxes to notify; we'll only notify each one once
                while (c.moveToNext()) {
                    messageCount++;
                    long mailboxId = c.getLong(0);
                    if (!mailboxesToNotify.contains(mailboxId)) {
                        mailboxesToNotify.add(mailboxId);
                    }
                }
            } finally {
                c.close();
            }

            // Request service from the mailbox
            for (Long mailboxId: mailboxesToNotify) {
                ExchangeService.serviceRequest(mailboxId, ExchangeService.SYNC_UPSYNC);
            }
        } catch (ProviderUnavailableException e) {
            Log.e("EmailSyncAlarmReceiver", "EmailProvider unavailable; aborting alarm receiver");
        }
    }
}
