package android.content;

import android.Manifest;
import android.accounts.Account;
import android.database.Cursor;
import android.database.DatabaseUtils;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;
import android.provider.Sync;
import android.text.TextUtils;
import android.util.Config;
import android.util.Log;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;

import com.google.android.collect.Sets;

/**
 * ContentProvider that tracks the sync data and overall sync
 * history on the device.
 * 
 * @hide
 */
public class SyncStorageEngine {
    private static final String TAG = "SyncManager";

    private static final String DATABASE_NAME = "syncmanager.db";
    private static final int DATABASE_VERSION = 11;

    private static final int STATS = 1;
    private static final int STATS_ID = 2;
    private static final int HISTORY = 3;
    private static final int HISTORY_ID = 4;
    private static final int SETTINGS = 5;
    private static final int PENDING = 7;
    private static final int ACTIVE = 8;
    private static final int STATUS = 9;

    private static final UriMatcher sURLMatcher =
            new UriMatcher(UriMatcher.NO_MATCH);

    private static final HashMap<String,String> HISTORY_PROJECTION_MAP;
    private static final HashMap<String,String> PENDING_PROJECTION_MAP;
    private static final HashMap<String,String> ACTIVE_PROJECTION_MAP;
    private static final HashMap<String,String> STATUS_PROJECTION_MAP;

    private final Context mContext;
    private final SQLiteOpenHelper mOpenHelper;
    private static SyncStorageEngine sSyncStorageEngine = null;

    static {
        sURLMatcher.addURI("sync", "stats", STATS);
        sURLMatcher.addURI("sync", "stats/#", STATS_ID);
        sURLMatcher.addURI("sync", "history", HISTORY);
        sURLMatcher.addURI("sync", "history/#", HISTORY_ID);
        sURLMatcher.addURI("sync", "settings", SETTINGS);
        sURLMatcher.addURI("sync", "status", STATUS);
        sURLMatcher.addURI("sync", "active", ACTIVE);
        sURLMatcher.addURI("sync", "pending", PENDING);

        HashMap<String,String> map;
        PENDING_PROJECTION_MAP = map = new HashMap<String,String>();
        map.put(Sync.History._ID, Sync.History._ID);
        map.put(Sync.History.ACCOUNT, Sync.History.ACCOUNT);
        map.put(Sync.History.ACCOUNT_TYPE, Sync.History.ACCOUNT_TYPE);
        map.put(Sync.History.AUTHORITY, Sync.History.AUTHORITY);

        ACTIVE_PROJECTION_MAP = map = new HashMap<String,String>();
        map.put(Sync.History._ID, Sync.History._ID);
        map.put(Sync.History.ACCOUNT, Sync.History.ACCOUNT);
        map.put(Sync.History.ACCOUNT_TYPE, Sync.History.ACCOUNT_TYPE);
        map.put(Sync.History.AUTHORITY, Sync.History.AUTHORITY);
        map.put("startTime", "startTime");

        HISTORY_PROJECTION_MAP = map = new HashMap<String,String>();
        map.put(Sync.History._ID, "history._id as _id");
        map.put(Sync.History.ACCOUNT, "stats.account as account");
        map.put(Sync.History.ACCOUNT_TYPE, "stats.account_type as account_type");
        map.put(Sync.History.AUTHORITY, "stats.authority as authority");
        map.put(Sync.History.EVENT, Sync.History.EVENT);
        map.put(Sync.History.EVENT_TIME, Sync.History.EVENT_TIME);
        map.put(Sync.History.ELAPSED_TIME, Sync.History.ELAPSED_TIME);
        map.put(Sync.History.SOURCE, Sync.History.SOURCE);
        map.put(Sync.History.UPSTREAM_ACTIVITY, Sync.History.UPSTREAM_ACTIVITY);
        map.put(Sync.History.DOWNSTREAM_ACTIVITY, Sync.History.DOWNSTREAM_ACTIVITY);
        map.put(Sync.History.MESG, Sync.History.MESG);

        STATUS_PROJECTION_MAP = map = new HashMap<String,String>();
        map.put(Sync.Status._ID, "status._id as _id");
        map.put(Sync.Status.ACCOUNT, "stats.account as account");
        map.put(Sync.Status.ACCOUNT_TYPE, "stats.account_type as account_type");
        map.put(Sync.Status.AUTHORITY, "stats.authority as authority");
        map.put(Sync.Status.TOTAL_ELAPSED_TIME, Sync.Status.TOTAL_ELAPSED_TIME);
        map.put(Sync.Status.NUM_SYNCS, Sync.Status.NUM_SYNCS);
        map.put(Sync.Status.NUM_SOURCE_LOCAL, Sync.Status.NUM_SOURCE_LOCAL);
        map.put(Sync.Status.NUM_SOURCE_POLL, Sync.Status.NUM_SOURCE_POLL);
        map.put(Sync.Status.NUM_SOURCE_SERVER, Sync.Status.NUM_SOURCE_SERVER);
        map.put(Sync.Status.NUM_SOURCE_USER, Sync.Status.NUM_SOURCE_USER);
        map.put(Sync.Status.LAST_SUCCESS_SOURCE, Sync.Status.LAST_SUCCESS_SOURCE);
        map.put(Sync.Status.LAST_SUCCESS_TIME, Sync.Status.LAST_SUCCESS_TIME);
        map.put(Sync.Status.LAST_FAILURE_SOURCE, Sync.Status.LAST_FAILURE_SOURCE);
        map.put(Sync.Status.LAST_FAILURE_TIME, Sync.Status.LAST_FAILURE_TIME);
        map.put(Sync.Status.LAST_FAILURE_MESG, Sync.Status.LAST_FAILURE_MESG);
        map.put(Sync.Status.PENDING, Sync.Status.PENDING);
    }

    private static final String[] STATS_ACCOUNT_PROJECTION =
            new String[] { Sync.Stats.ACCOUNT, Sync.Stats.ACCOUNT_TYPE };

    private static final int MAX_HISTORY_EVENTS_TO_KEEP = 5000;

    private static final String SELECT_INITIAL_FAILURE_TIME_QUERY_STRING = ""
            + "SELECT min(a) "
            + "FROM ("
            + "  SELECT initialFailureTime AS a "
            + "  FROM status "
            + "  WHERE stats_id=? AND a IS NOT NULL "
            + "    UNION "
            + "  SELECT ? AS a"
            + " )";

    private SyncStorageEngine(Context context) {
        mContext = context;
        mOpenHelper = new SyncStorageEngine.DatabaseHelper(context);
        sSyncStorageEngine = this;
    }

    public static SyncStorageEngine newTestInstance(Context context) {
        return new SyncStorageEngine(context);
    }

    public static void init(Context context) {
        if (sSyncStorageEngine != null) {
            throw new IllegalStateException("already initialized");
        }
        sSyncStorageEngine = new SyncStorageEngine(context);
    }

    public static SyncStorageEngine getSingleton() {
        if (sSyncStorageEngine == null) {
            throw new IllegalStateException("not initialized");
        }
        return sSyncStorageEngine;
    }

    private class DatabaseHelper extends SQLiteOpenHelper {
        DatabaseHelper(Context context) {
            super(context, DATABASE_NAME, null, DATABASE_VERSION);
        }

        @Override
        public void onCreate(SQLiteDatabase db) {
            db.execSQL("CREATE TABLE pending ("
                    + "_id INTEGER PRIMARY KEY,"
                    + "authority TEXT NOT NULL,"
                    + "account TEXT NOT NULL,"
                    + "account_type TEXT NOT NULL,"
                    + "extras BLOB NOT NULL,"
                    + "source INTEGER NOT NULL"
                    + ");");

            db.execSQL("CREATE TABLE stats (" +
                       "_id INTEGER PRIMARY KEY," +
                       "account TEXT, " +
                       "account_type TEXT, " +
                       "authority TEXT, " +
                       "syncdata TEXT, " +
                       "UNIQUE (account, authority)" +
                       ");");

            db.execSQL("CREATE TABLE history (" +
                       "_id INTEGER PRIMARY KEY," +
                       "stats_id INTEGER," +
                       "eventTime INTEGER," +
                       "elapsedTime INTEGER," +
                       "source INTEGER," +
                       "event INTEGER," +
                       "upstreamActivity INTEGER," +
                       "downstreamActivity INTEGER," +
                       "mesg TEXT);");

            db.execSQL("CREATE TABLE status ("
                    + "_id INTEGER PRIMARY KEY,"
                    + "stats_id INTEGER NOT NULL,"
                    + "totalElapsedTime INTEGER NOT NULL DEFAULT 0,"
                    + "numSyncs INTEGER NOT NULL DEFAULT 0,"
                    + "numSourcePoll INTEGER NOT NULL DEFAULT 0,"
                    + "numSourceServer INTEGER NOT NULL DEFAULT 0,"
                    + "numSourceLocal INTEGER NOT NULL DEFAULT 0,"
                    + "numSourceUser INTEGER NOT NULL DEFAULT 0,"
                    + "lastSuccessTime INTEGER,"
                    + "lastSuccessSource INTEGER,"
                    + "lastFailureTime INTEGER,"
                    + "lastFailureSource INTEGER,"
                    + "lastFailureMesg STRING,"
                    + "initialFailureTime INTEGER,"
                    + "pending INTEGER NOT NULL DEFAULT 0);");

            db.execSQL("CREATE TABLE active ("
                    + "_id INTEGER PRIMARY KEY,"
                    + "authority TEXT,"
                    + "account TEXT,"
                    + "account_type TEXT,"
                    + "startTime INTEGER);");

            db.execSQL("CREATE INDEX historyEventTime ON history (eventTime)");

            db.execSQL("CREATE TABLE settings (" +
                       "name TEXT PRIMARY KEY," +
                       "value TEXT);");
        }

        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
            if (oldVersion == 9) {
                Log.w(TAG, "Upgrading database from version " + oldVersion + " to "
                        + newVersion + ", which will preserve old data");
                db.execSQL("ALTER TABLE status ADD COLUMN initialFailureTime INTEGER");
                oldVersion++;
            }

            if (oldVersion == 10) {
                Log.w(TAG, "Upgrading database from version " + oldVersion + " to "
                        + newVersion + ", which will preserve old data");
                db.execSQL("ALTER TABLE pending ADD COLUMN account_type TEXT");
                db.execSQL("ALTER TABLE stats ADD COLUMN account_type TEXT");
                db.execSQL("ALTER TABLE active ADD COLUMN account_type TEXT");

                db.execSQL("UPDATE pending SET account_type='com.google.GAIA'");
                db.execSQL("UPDATE stats SET account_type='com.google.GAIA'");
                db.execSQL("UPDATE active SET account_type='com.google.GAIA'");
                oldVersion++;
            }

            if (oldVersion == newVersion) {
                return;
            }

            Log.w(TAG, "Upgrading database from version " + oldVersion + " to "
                    + newVersion + ", which will destroy all old data");
            db.execSQL("DROP TABLE IF EXISTS pending");
            db.execSQL("DROP TABLE IF EXISTS stats");
            db.execSQL("DROP TABLE IF EXISTS history");
            db.execSQL("DROP TABLE IF EXISTS settings");
            db.execSQL("DROP TABLE IF EXISTS active");
            db.execSQL("DROP TABLE IF EXISTS status");
            onCreate(db);
        }

        @Override
        public void onOpen(SQLiteDatabase db) {
            if (!db.isReadOnly()) {
                db.delete("active", null, null);
                db.insert("active", "account", null);
            }
        }
    }

    protected void doDatabaseCleanup(Account[] accounts) {
        HashSet<Account> currentAccounts = Sets.newHashSet(accounts);
        SQLiteDatabase db = mOpenHelper.getWritableDatabase();
        Cursor cursor = db.query("stats", STATS_ACCOUNT_PROJECTION,
                null /* where */, null /* where args */,
                Sync.Stats.ACCOUNT + "," + Sync.Stats.ACCOUNT_TYPE,
                null /* having */, null /* order by */);
        try {
            while (cursor.moveToNext()) {
                String accountName = cursor.getString(0);
                String accountType = cursor.getString(1);
                final Account account = new Account(accountName, accountType);
                if (!currentAccounts.contains(account)) {
                    String where = Sync.Stats.ACCOUNT + "=? AND " + Sync.Stats.ACCOUNT_TYPE + "=?";
                    int numDeleted;
                    numDeleted = db.delete("stats", where,
                            new String[]{account.mName, account.mType});
                    if (Config.LOGD) {
                        Log.d(TAG, "deleted " + numDeleted
                                + " records from stats table"
                                + " for account " + account);
                    }
                }
            }
        } finally {
            cursor.close();
        }
    }

    protected void setActiveSync(SyncManager.ActiveSyncContext activeSyncContext) {
        if (activeSyncContext != null) {
            updateActiveSync(activeSyncContext.mSyncOperation.account,
                    activeSyncContext.mSyncOperation.authority, activeSyncContext.mStartTime);
        } else {
            // we indicate that the sync is not active by passing null for all the parameters
            updateActiveSync(null, null, null);
        }
    }

    private int updateActiveSync(Account account, String authority, Long startTime) {
        SQLiteDatabase db = mOpenHelper.getWritableDatabase();
        ContentValues values = new ContentValues();
        values.put("account", account == null ? null : account.mName);
        values.put("account_type", account == null ? null : account.mType);
        values.put("authority", authority);
        values.put("startTime", startTime);
        int numChanges = db.update("active", values, null, null);
        if (numChanges > 0) {
            mContext.getContentResolver().notifyChange(Sync.Active.CONTENT_URI,
                    null /* this change wasn't made through an observer */);
        }
        return numChanges;
    }

    /**
     * Implements the {@link ContentProvider#query} method
     */
    public Cursor query(Uri url, String[] projectionIn,
            String selection, String[] selectionArgs, String sort) {
        SQLiteQueryBuilder qb = new SQLiteQueryBuilder();

        // Generate the body of the query
        int match = sURLMatcher.match(url);
        String groupBy = null;
        switch (match) {
            case STATS:
                qb.setTables("stats");
                break;
            case STATS_ID:
                qb.setTables("stats");
                qb.appendWhere("_id=");
                qb.appendWhere(url.getPathSegments().get(1));
                break;
            case HISTORY:
                // join the stats and history tables, so the caller can get
                // the account and authority information as part of this query.
                qb.setTables("stats, history");
                qb.setProjectionMap(HISTORY_PROJECTION_MAP);
                qb.appendWhere("stats._id = history.stats_id");
                break;
            case ACTIVE:
                qb.setTables("active");
                qb.setProjectionMap(ACTIVE_PROJECTION_MAP);
                qb.appendWhere("account is not null");
                break;
            case PENDING:
                qb.setTables("pending");
                qb.setProjectionMap(PENDING_PROJECTION_MAP);
                groupBy = "account, authority";
                break;
            case STATUS:
                // join the stats and status tables, so the caller can get
                // the account and authority information as part of this query.
                qb.setTables("stats, status");
                qb.setProjectionMap(STATUS_PROJECTION_MAP);
                qb.appendWhere("stats._id = status.stats_id");
                break;
            case HISTORY_ID:
                // join the stats and history tables, so the caller can get
                // the account and authority information as part of this query.
                qb.setTables("stats, history");
                qb.setProjectionMap(HISTORY_PROJECTION_MAP);
                qb.appendWhere("stats._id = history.stats_id");
                qb.appendWhere("AND history._id=");
                qb.appendWhere(url.getPathSegments().get(1));
                break;
            case SETTINGS:
                qb.setTables("settings");
                break;
            default:
                throw new IllegalArgumentException("Unknown URL " + url);
        }

        if (match == SETTINGS) {
            mContext.enforceCallingOrSelfPermission(Manifest.permission.READ_SYNC_SETTINGS,
                    "no permission to read the sync settings");
        } else {
            mContext.enforceCallingOrSelfPermission(Manifest.permission.READ_SYNC_STATS,
                    "no permission to read the sync stats");
        }
        SQLiteDatabase db = mOpenHelper.getReadableDatabase();
        Cursor c = qb.query(db, projectionIn, selection, selectionArgs, groupBy, null, sort);
        c.setNotificationUri(mContext.getContentResolver(), url);
        return c;
    }

    /**
     * Implements the {@link ContentProvider#insert} method
     * @param callerIsTheProvider true if this is being called via the
     *  {@link ContentProvider#insert} in method rather than directly.
     * @throws UnsupportedOperationException if callerIsTheProvider is true and the url isn't
     *   for the Settings table.
     */
    public Uri insert(boolean callerIsTheProvider, Uri url, ContentValues values) {
        String table;
        long rowID;
        SQLiteDatabase db = mOpenHelper.getWritableDatabase();
        final int match = sURLMatcher.match(url);
        checkCaller(callerIsTheProvider, match);
        switch (match) {
            case SETTINGS:
                mContext.enforceCallingOrSelfPermission(Manifest.permission.WRITE_SYNC_SETTINGS,
                        "no permission to write the sync settings");
                table = "settings";
                rowID = db.replace(table, null, values);
                break;
            default:
                throw new IllegalArgumentException("Unknown URL " + url);
        }


        if (rowID > 0) {
            mContext.getContentResolver().notifyChange(url, null /* observer */);
            return Uri.parse("content://sync/" + table + "/" + rowID);
        }

        return null;
    }

    private static void checkCaller(boolean callerIsTheProvider, int match) {
        if (callerIsTheProvider && match != SETTINGS) {
            throw new UnsupportedOperationException(
                    "only the settings are modifiable via the ContentProvider interface");
        }
    }

    /**
     * Implements the {@link ContentProvider#delete} method
     * @param callerIsTheProvider true if this is being called via the
     *  {@link ContentProvider#delete} in method rather than directly.
     * @throws UnsupportedOperationException if callerIsTheProvider is true and the url isn't
     *   for the Settings table.
     */
    public int delete(boolean callerIsTheProvider, Uri url, String where, String[] whereArgs) {
        SQLiteDatabase db = mOpenHelper.getWritableDatabase();
        int match = sURLMatcher.match(url);

        int numRows;
        switch (match) {
            case SETTINGS:
                mContext.enforceCallingOrSelfPermission(Manifest.permission.WRITE_SYNC_SETTINGS,
                        "no permission to write the sync settings");
                numRows = db.delete("settings", where, whereArgs);
                break;
            default:
                throw new UnsupportedOperationException("Cannot delete URL: " + url);
        }

        if (numRows > 0) {
            mContext.getContentResolver().notifyChange(url, null /* observer */);
        }
        return numRows;
    }

    /**
     * Implements the {@link ContentProvider#update} method
     * @param callerIsTheProvider true if this is being called via the
     *  {@link ContentProvider#update} in method rather than directly.
     * @throws UnsupportedOperationException if callerIsTheProvider is true and the url isn't
     *   for the Settings table.
     */
    public int update(boolean callerIsTheProvider, Uri url, ContentValues initialValues,
            String where, String[] whereArgs) {
        switch (sURLMatcher.match(url)) {
            case SETTINGS:
                throw new UnsupportedOperationException("updating url " + url
                        + " is not allowed, use insert instead");
            default:
                throw new UnsupportedOperationException("Cannot update URL: " + url);
        }
    }

    /**
     * Implements the {@link ContentProvider#getType} method
     */
    public String getType(Uri url) {
        int match = sURLMatcher.match(url);
        switch (match) {
            case SETTINGS:
                return "vnd.android.cursor.dir/sync-settings";
            default:
                throw new IllegalArgumentException("Unknown URL");
        }
    }

    protected Uri insertIntoPending(ContentValues values) {
        SQLiteDatabase db = mOpenHelper.getWritableDatabase();
        try {
            db.beginTransaction();
            long rowId = db.insert("pending", Sync.Pending.ACCOUNT, values);
            if (rowId < 0) return null;
            String accountName = values.getAsString(Sync.Pending.ACCOUNT);
            String accountType = values.getAsString(Sync.Pending.ACCOUNT_TYPE);
            final Account account = new Account(accountName, accountType);
            String authority = values.getAsString(Sync.Pending.AUTHORITY);

            long statsId = createStatsRowIfNecessary(account, authority);
            createStatusRowIfNecessary(statsId);

            values.clear();
            values.put(Sync.Status.PENDING, 1);
            int numUpdatesStatus = db.update("status", values, "stats_id=" + statsId, null);

            db.setTransactionSuccessful();

            mContext.getContentResolver().notifyChange(Sync.Pending.CONTENT_URI,
                    null /* no observer initiated this change */);
            if (numUpdatesStatus > 0) {
                mContext.getContentResolver().notifyChange(Sync.Status.CONTENT_URI,
                        null /* no observer initiated this change */);
            }
            return ContentUris.withAppendedId(Sync.Pending.CONTENT_URI, rowId);
        } finally {
            db.endTransaction();
        }
    }

    int deleteFromPending(long rowId) {
        SQLiteDatabase db = mOpenHelper.getWritableDatabase();
        db.beginTransaction();
        try {
            Account account;
            String authority;
            Cursor c = db.query("pending",
                    new String[]{Sync.Pending.ACCOUNT, Sync.Pending.ACCOUNT_TYPE,
                            Sync.Pending.AUTHORITY},
                    "_id=" + rowId, null, null, null, null);
            try {
                if (c.getCount() != 1) {
                    return 0;
                }
                c.moveToNext();
                String accountName = c.getString(0);
                String accountType = c.getString(1);
                account = new Account(accountName, accountType);
                authority = c.getString(2);
            } finally {
                c.close();
            }
            db.delete("pending", "_id=" + rowId, null /* no where args */);
            final String[] accountAuthorityWhereArgs =
                    new String[]{account.mName, account.mType, authority};
            boolean isPending = 0 < DatabaseUtils.longForQuery(db,
                    "SELECT COUNT(*)"
                            + " FROM PENDING"
                            + " WHERE account=? AND account_type=? AND authority=?",
                    accountAuthorityWhereArgs);
            if (!isPending) {
                long statsId = createStatsRowIfNecessary(account, authority);
                db.execSQL("UPDATE status SET pending=0 WHERE stats_id=" + statsId);
            }
            db.setTransactionSuccessful();

            mContext.getContentResolver().notifyChange(Sync.Pending.CONTENT_URI,
                    null /* no observer initiated this change */);
            if (!isPending) {
                mContext.getContentResolver().notifyChange(Sync.Status.CONTENT_URI,
                        null /* no observer initiated this change */);
            }
            return 1;
        } finally {
            db.endTransaction();
        }
    }

    int clearPending() {
        SQLiteDatabase db = mOpenHelper.getWritableDatabase();
        db.beginTransaction();
        try {
            int numChanges = db.delete("pending", null, null /* no where args */);
            if (numChanges > 0) {
                db.execSQL("UPDATE status SET pending=0");
                mContext.getContentResolver().notifyChange(Sync.Pending.CONTENT_URI,
                        null /* no observer initiated this change */);
                mContext.getContentResolver().notifyChange(Sync.Status.CONTENT_URI,
                        null /* no observer initiated this change */);
            }
            db.setTransactionSuccessful();
            return numChanges;
        } finally {
            db.endTransaction();
        }
    }

    /**
     * Returns a cursor over all the pending syncs in no particular order. This cursor is not
     * "live", in that if changes are made to the pending table any observers on this cursor
     * will not be notified.
     * @param projection Return only these columns. If null then all columns are returned.
     * @return the cursor of pending syncs
     */
    public Cursor getPendingSyncsCursor(String[] projection) {
        SQLiteDatabase db = mOpenHelper.getReadableDatabase();
        return db.query("pending", projection, null, null, null, null, null);
    }

    // @VisibleForTesting
    static final long MILLIS_IN_4WEEKS = 1000L * 60 * 60 * 24 * 7 * 4;

    private boolean purgeOldHistoryEvents(long now) {
        // remove events that are older than MILLIS_IN_4WEEKS
        SQLiteDatabase db = mOpenHelper.getWritableDatabase();
        int numDeletes = db.delete("history", "eventTime<" + (now - MILLIS_IN_4WEEKS), null);
        if (Log.isLoggable(TAG, Log.VERBOSE)) {
            if (numDeletes > 0) {
                Log.v(TAG, "deleted " + numDeletes + " old event(s) from the sync history");
            }
        }

        // keep only the last MAX_HISTORY_EVENTS_TO_KEEP history events
        numDeletes += db.delete("history", "eventTime < (select min(eventTime) from "
                + "(select eventTime from history order by eventTime desc limit ?))",
                new String[]{String.valueOf(MAX_HISTORY_EVENTS_TO_KEEP)});
        
        return numDeletes > 0;
    }

    public long insertStartSyncEvent(Account account, String authority, long now, int source) {
        SQLiteDatabase db = mOpenHelper.getWritableDatabase();
        long statsId = createStatsRowIfNecessary(account, authority);

        purgeOldHistoryEvents(now);
        ContentValues values = new ContentValues();
        values.put(Sync.History.STATS_ID, statsId);
        values.put(Sync.History.EVENT_TIME, now);
        values.put(Sync.History.SOURCE, source);
        values.put(Sync.History.EVENT, Sync.History.EVENT_START);
        long rowId = db.insert("history", null, values);
        mContext.getContentResolver().notifyChange(Sync.History.CONTENT_URI, null /* observer */);
        mContext.getContentResolver().notifyChange(Sync.Status.CONTENT_URI, null /* observer */);
        return rowId;
    }

    public void stopSyncEvent(long historyId, long elapsedTime, String resultMessage,
            long downstreamActivity, long upstreamActivity) {
        SQLiteDatabase db = mOpenHelper.getWritableDatabase();
        db.beginTransaction();
        try {
            ContentValues values = new ContentValues();
            values.put(Sync.History.ELAPSED_TIME, elapsedTime);
            values.put(Sync.History.EVENT, Sync.History.EVENT_STOP);
            values.put(Sync.History.MESG, resultMessage);
            values.put(Sync.History.DOWNSTREAM_ACTIVITY, downstreamActivity);
            values.put(Sync.History.UPSTREAM_ACTIVITY, upstreamActivity);

            int count = db.update("history", values, "_id=?",
                    new String[]{Long.toString(historyId)});
            // We think that count should always be 1 but don't want to change this until after
            // launch.
            if (count > 0) {
                int source = (int) DatabaseUtils.longForQuery(db,
                        "SELECT source FROM history WHERE _id=" + historyId, null);
                long eventTime = DatabaseUtils.longForQuery(db,
                        "SELECT eventTime FROM history WHERE _id=" + historyId, null);
                long statsId = DatabaseUtils.longForQuery(db,
                        "SELECT stats_id FROM history WHERE _id=" + historyId, null);

                createStatusRowIfNecessary(statsId);

                // update the status table to reflect this sync
                StringBuilder sb = new StringBuilder();
                ArrayList<String> bindArgs = new ArrayList<String>();
                sb.append("UPDATE status SET");
                sb.append(" numSyncs=numSyncs+1");
                sb.append(", totalElapsedTime=totalElapsedTime+" + elapsedTime);
                switch (source) {
                    case Sync.History.SOURCE_LOCAL:
                        sb.append(", numSourceLocal=numSourceLocal+1");
                        break;
                    case Sync.History.SOURCE_POLL:
                        sb.append(", numSourcePoll=numSourcePoll+1");
                        break;
                    case Sync.History.SOURCE_USER:
                        sb.append(", numSourceUser=numSourceUser+1");
                        break;
                    case Sync.History.SOURCE_SERVER:
                        sb.append(", numSourceServer=numSourceServer+1");
                        break;
                }

                final String statsIdString = String.valueOf(statsId);
                final long lastSyncTime = (eventTime + elapsedTime);
                if (Sync.History.MESG_SUCCESS.equals(resultMessage)) {
                    // - if successful, update the successful columns
                    sb.append(", lastSuccessTime=" + lastSyncTime);
                    sb.append(", lastSuccessSource=" + source);
                    sb.append(", lastFailureTime=null");
                    sb.append(", lastFailureSource=null");
                    sb.append(", lastFailureMesg=null");
                    sb.append(", initialFailureTime=null");
                } else if (!Sync.History.MESG_CANCELED.equals(resultMessage)) {
                    sb.append(", lastFailureTime=" + lastSyncTime);
                    sb.append(", lastFailureSource=" + source);
                    sb.append(", lastFailureMesg=?");
                    bindArgs.add(resultMessage);
                    long initialFailureTime = DatabaseUtils.longForQuery(db,
                            SELECT_INITIAL_FAILURE_TIME_QUERY_STRING, 
                            new String[]{statsIdString, String.valueOf(lastSyncTime)});
                    sb.append(", initialFailureTime=" + initialFailureTime);
                }
                sb.append(" WHERE stats_id=?");
                bindArgs.add(statsIdString);
                db.execSQL(sb.toString(), bindArgs.toArray());
                db.setTransactionSuccessful();
                mContext.getContentResolver().notifyChange(Sync.History.CONTENT_URI,
                        null /* observer */);
                mContext.getContentResolver().notifyChange(Sync.Status.CONTENT_URI,
                        null /* observer */);
            }
        } finally {
            db.endTransaction();
        }
    }

    /**
     * If sync is failing for any of the provider/accounts then determine the time at which it
     * started failing and return the earliest time over all the provider/accounts. If none are
     * failing then return 0.
     */
    public long getInitialSyncFailureTime() {
        SQLiteDatabase db = mOpenHelper.getReadableDatabase();
        // Join the settings for a provider with the status so that we can easily
        // check if each provider is enabled for syncing. We also join in the overall
        // enabled flag ("listen_for_tickles") to each row so that we don't need to
        // make a separate DB lookup to access it.
        Cursor c = db.rawQuery(""
                + "SELECT initialFailureTime, s1.value, s2.value "
                + "FROM status "
                + "LEFT JOIN stats ON status.stats_id=stats._id "
                + "LEFT JOIN settings as s1 ON 'sync_provider_' || authority=s1.name "
                + "LEFT JOIN settings as s2 ON s2.name='listen_for_tickles' "
                + "where initialFailureTime is not null "
                + "  AND lastFailureMesg!=" + Sync.History.ERROR_TOO_MANY_DELETIONS
                + "  AND lastFailureMesg!=" + Sync.History.ERROR_AUTHENTICATION
                + "  AND lastFailureMesg!=" + Sync.History.ERROR_SYNC_ALREADY_IN_PROGRESS
                + "  AND authority!='subscribedfeeds' "
                + " ORDER BY initialFailureTime", null);
        try {
            while (c.moveToNext()) {
                // these settings default to true, so if they are null treat them as enabled
                final String providerEnabledString = c.getString(1);
                if (providerEnabledString != null && !Boolean.parseBoolean(providerEnabledString)) {
                    continue;
                }
                final String allEnabledString = c.getString(2);
                if (allEnabledString != null && !Boolean.parseBoolean(allEnabledString)) {
                    continue;
                }
                return c.getLong(0);
            }
        } finally {
            c.close();
        }
        return 0;
    }

    private void createStatusRowIfNecessary(long statsId) {
        SQLiteDatabase db = mOpenHelper.getWritableDatabase();
        boolean statusExists = 0 != DatabaseUtils.longForQuery(db,
                "SELECT count(*) FROM status WHERE stats_id=" + statsId, null);
        if (!statusExists) {
            ContentValues values = new ContentValues();
            values.put("stats_id", statsId);
            db.insert("status", null, values);
        }
    }

    private long createStatsRowIfNecessary(Account account, String authority) {
        SQLiteDatabase db = mOpenHelper.getWritableDatabase();
        StringBuilder where = new StringBuilder();
        where.append(Sync.Stats.ACCOUNT + "= ?");
        where.append(" and " + Sync.Stats.ACCOUNT_TYPE + "= ?");
        where.append(" and " + Sync.Stats.AUTHORITY + "= ?");
        Cursor cursor = query(Sync.Stats.CONTENT_URI,
                Sync.Stats.SYNC_STATS_PROJECTION,
                where.toString(), new String[] { account.mName, account.mType, authority },
                null /* order */);
        try {
            long id;
            if (cursor.moveToFirst()) {
                id = cursor.getLong(cursor.getColumnIndexOrThrow(Sync.Stats._ID));
            } else {
                ContentValues values = new ContentValues();
                values.put(Sync.Stats.ACCOUNT, account.mName);
                values.put(Sync.Stats.ACCOUNT_TYPE, account.mType);
                values.put(Sync.Stats.AUTHORITY, authority);
                id = db.insert("stats", null, values);
            }
            return id;
        } finally {
            cursor.close();
        }
    }
}
