/*
 * Copyright (C) 2006 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 android.content;

import android.database.Cursor;
import android.database.DatabaseUtils;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;
import android.os.Debug;
import android.provider.BaseColumns;
import static android.provider.SyncConstValue.*;
import android.text.TextUtils;
import android.util.Log;
import android.accounts.Account;

/**
 * @hide
 */
public abstract class AbstractTableMerger
{
    private ContentValues mValues;

    protected SQLiteDatabase mDb;
    protected String mTable;
    protected Uri mTableURL;
    protected String mDeletedTable;
    protected Uri mDeletedTableURL;
    static protected ContentValues mSyncMarkValues;
    static private boolean TRACE;

    static {
        mSyncMarkValues = new ContentValues();
        mSyncMarkValues.put(_SYNC_MARK, 1);
        TRACE = false;
    }

    private static final String TAG = "AbstractTableMerger";
    private static final String[] syncDirtyProjection =
            new String[] {_SYNC_DIRTY, BaseColumns._ID, _SYNC_ID, _SYNC_VERSION};
    private static final String[] syncIdAndVersionProjection =
            new String[] {_SYNC_ID, _SYNC_VERSION};

    private volatile boolean mIsMergeCancelled;

    private static final String SELECT_MARKED = _SYNC_MARK + "> 0 and "
            + _SYNC_ACCOUNT + "=? and " + _SYNC_ACCOUNT_TYPE + "=?";

    private static final String SELECT_BY_SYNC_ID_AND_ACCOUNT =
            _SYNC_ID +"=? and " + _SYNC_ACCOUNT + "=? and " + _SYNC_ACCOUNT_TYPE + "=?";
    private static final String SELECT_BY_ID = BaseColumns._ID +"=?";

    private static final String SELECT_UNSYNCED = ""
            + _SYNC_DIRTY + " > 0 and ((" + _SYNC_ACCOUNT + "=? AND " + _SYNC_ACCOUNT_TYPE + "=?) "
            + "or " + _SYNC_ACCOUNT + " is null)";

    public AbstractTableMerger(SQLiteDatabase database,
            String table, Uri tableURL, String deletedTable,
            Uri deletedTableURL)
    {
        mDb = database;
        mTable = table;
        mTableURL = tableURL;
        mDeletedTable = deletedTable;
        mDeletedTableURL = deletedTableURL;
        mValues = new ContentValues();
    }

    public abstract void insertRow(ContentProvider diffs,
            Cursor diffsCursor);
    public abstract void updateRow(long localPersonID,
            ContentProvider diffs, Cursor diffsCursor);
    public abstract void resolveRow(long localPersonID,
            String syncID, ContentProvider diffs, Cursor diffsCursor);

    /**
     * This is called when it is determined that a row should be deleted from the
     * ContentProvider. The localCursor is on a table from the local ContentProvider
     * and its current position is of the row that should be deleted. The localCursor
     * is only guaranteed to contain the BaseColumns.ID column so the implementation
     * of deleteRow() must query the database directly if other columns are needed.
     * <p>
     * It is the responsibility of the implementation of this method to ensure that the cursor
     * points to the next row when this method returns, either by calling Cursor.deleteRow() or
     * Cursor.next().
     *
     * @param localCursor The Cursor into the local table, which points to the row that
     *   is to be deleted.
     */
    public void deleteRow(Cursor localCursor) {
        localCursor.deleteRow();
    }

    /**
     * After {@link #merge} has completed, this method is called to send
     * notifications to {@link android.database.ContentObserver}s of changes
     * to the containing {@link ContentProvider}.  These notifications likely
     * do not want to request a sync back to the network.
     */
    protected abstract void notifyChanges();

    private static boolean findInCursor(Cursor cursor, int column, String id) {
        while (!cursor.isAfterLast() && !cursor.isNull(column)) {
            int comp = id.compareTo(cursor.getString(column));
            if (comp > 0) {
                cursor.moveToNext();
                continue;
            }
            return comp == 0;
        }
        return false;
    }

    public void onMergeCancelled() {
        mIsMergeCancelled = true;
    }

    /**
     * Carry out a merge of the given diffs, and add the results to
     * the given MergeResult.  If we are the first merge to find
     * client-side diffs, we'll use the given ContentProvider to
     * construct a temporary instance to hold them.
     */
    public void merge(final SyncContext context,
            final Account account,
            final SyncableContentProvider serverDiffs,
            TempProviderSyncResult result,
            SyncResult syncResult, SyncableContentProvider temporaryInstanceFactory) {
        mIsMergeCancelled = false;
        if (serverDiffs != null) {
            if (!mDb.isDbLockedByCurrentThread()) {
                throw new IllegalStateException("this must be called from within a DB transaction");
            }
            mergeServerDiffs(context, account, serverDiffs, syncResult);
            notifyChanges();
        }

        if (result != null) {
            findLocalChanges(result, temporaryInstanceFactory, account, syncResult);
        }
        if (Log.isLoggable(TAG, Log.VERBOSE)) Log.v(TAG, "merge complete");
    }

    /**
     * @hide this is public for testing purposes only
     */
    public void mergeServerDiffs(SyncContext context,
            Account account, SyncableContentProvider serverDiffs, SyncResult syncResult) {
        boolean diffsArePartial = serverDiffs.getContainsDiffs();
        // mark the current rows so that we can distinguish these from new
        // inserts that occur during the merge
        mDb.update(mTable, mSyncMarkValues, null, null);
        if (mDeletedTable != null) {
            mDb.update(mDeletedTable, mSyncMarkValues, null, null);
        }

        Cursor localCursor = null;
        Cursor deletedCursor = null;
        Cursor diffsCursor = null;
        try {
            // load the local database entries, so we can merge them with the server
            final String[] accountSelectionArgs = new String[]{account.mName, account.mType};
            localCursor = mDb.query(mTable, syncDirtyProjection,
                    SELECT_MARKED, accountSelectionArgs, null, null,
                    mTable + "." + _SYNC_ID);
            if (mDeletedTable != null) {
                deletedCursor = mDb.query(mDeletedTable, syncIdAndVersionProjection,
                        SELECT_MARKED, accountSelectionArgs, null, null,
                        mDeletedTable + "." + _SYNC_ID);
            } else {
                deletedCursor =
                        mDb.rawQuery("select 'a' as _sync_id, 'b' as _sync_version limit 0", null);
            }

            // Apply updates and insertions from the server
            diffsCursor = serverDiffs.query(mTableURL,
                    null, null, null, mTable + "." + _SYNC_ID);
            int deletedSyncIDColumn = deletedCursor.getColumnIndexOrThrow(_SYNC_ID);
            int deletedSyncVersionColumn = deletedCursor.getColumnIndexOrThrow(_SYNC_VERSION);
            int serverSyncIDColumn = diffsCursor.getColumnIndexOrThrow(_SYNC_ID);
            int serverSyncVersionColumn = diffsCursor.getColumnIndexOrThrow(_SYNC_VERSION);
            int serverSyncLocalIdColumn = diffsCursor.getColumnIndexOrThrow(_SYNC_LOCAL_ID);

            String lastSyncId = null;
            int diffsCount = 0;
            int localCount = 0;
            localCursor.moveToFirst();
            deletedCursor.moveToFirst();
            while (diffsCursor.moveToNext()) {
                if (mIsMergeCancelled) {
                    return;
                }
                mDb.yieldIfContended();
                String serverSyncId = diffsCursor.getString(serverSyncIDColumn);
                String serverSyncVersion = diffsCursor.getString(serverSyncVersionColumn);
                long localRowId = 0;
                String localSyncVersion = null;

                diffsCount++;
                context.setStatusText("Processing " + diffsCount + "/"
                        + diffsCursor.getCount());
                if (Log.isLoggable(TAG, Log.VERBOSE)) Log.v(TAG, "processing server entry " +
                        diffsCount + ", " + serverSyncId);

                if (TRACE) {
                    if (diffsCount == 10) {
                        Debug.startMethodTracing("atmtrace");
                    }
                    if (diffsCount == 20) {
                        Debug.stopMethodTracing();
                    }
                }

                boolean conflict = false;
                boolean update = false;
                boolean insert = false;

                if (Log.isLoggable(TAG, Log.VERBOSE)) {
                    Log.v(TAG, "found event with serverSyncID " + serverSyncId);
                }
                if (TextUtils.isEmpty(serverSyncId)) {
                    if (Log.isLoggable(TAG, Log.VERBOSE)) {
                        Log.e(TAG, "server entry doesn't have a serverSyncID");
                    }
                    continue;
                }

                // It is possible that the sync adapter wrote the same record multiple times,
                // e.g. if the same record came via multiple feeds. If this happens just ignore
                // the duplicate records.
                if (serverSyncId.equals(lastSyncId)) {
                    if (Log.isLoggable(TAG, Log.VERBOSE)) {
                        Log.v(TAG, "skipping record with duplicate remote server id " + lastSyncId);
                    }
                    continue;
                }
                lastSyncId = serverSyncId;

                String localSyncID = null;
                boolean localSyncDirty = false;

                while (!localCursor.isAfterLast()) {
                    if (mIsMergeCancelled) {
                        return;
                    }
                    localCount++;
                    localSyncID = localCursor.getString(2);

                    // If the local record doesn't have a _sync_id then
                    // it is new. Ignore it for now, we will send an insert
                    // the the server later.
                    if (TextUtils.isEmpty(localSyncID)) {
                        if (Log.isLoggable(TAG, Log.VERBOSE)) {
                            Log.v(TAG, "local record " +
                                    localCursor.getLong(1) +
                                    " has no _sync_id, ignoring");
                        }
                        localCursor.moveToNext();
                        localSyncID = null;
                        continue;
                    }

                    int comp = serverSyncId.compareTo(localSyncID);

                    // the local DB has a record that the server doesn't have
                    if (comp > 0) {
                        if (Log.isLoggable(TAG, Log.VERBOSE)) {
                            Log.v(TAG, "local record " +
                                    localCursor.getLong(1) +
                                    " has _sync_id " + localSyncID +
                                    " that is < server _sync_id " + serverSyncId);
                        }
                        if (diffsArePartial) {
                            localCursor.moveToNext();
                        } else {
                            deleteRow(localCursor);
                            if (mDeletedTable != null) {
                                mDb.delete(mDeletedTable, _SYNC_ID +"=?", new String[] {localSyncID});
                            }
                            syncResult.stats.numDeletes++;
                            mDb.yieldIfContended();
                        }
                        localSyncID = null;
                        continue;
                    }

                    // the server has a record that the local DB doesn't have
                    if (comp < 0) {
                        if (Log.isLoggable(TAG, Log.VERBOSE)) {
                            Log.v(TAG, "local record " +
                                    localCursor.getLong(1) +
                                    " has _sync_id " + localSyncID +
                                    " that is > server _sync_id " + serverSyncId);
                        }
                        localSyncID = null;
                    }

                    // the server and the local DB both have this record
                    if (comp == 0) {
                        if (Log.isLoggable(TAG, Log.VERBOSE)) {
                            Log.v(TAG, "local record " +
                                    localCursor.getLong(1) +
                                    " has _sync_id " + localSyncID +
                                    " that matches the server _sync_id");
                        }
                        localSyncDirty = localCursor.getInt(0) != 0;
                        localRowId = localCursor.getLong(1);
                        localSyncVersion = localCursor.getString(3);
                        localCursor.moveToNext();
                    }

                    break;
                }

                // If this record is in the deleted table then update the server version
                // in the deleted table, if necessary, and then ignore it here.
                // We will send a deletion indication to the server down a
                // little further.
                if (findInCursor(deletedCursor, deletedSyncIDColumn, serverSyncId)) {
                    if (Log.isLoggable(TAG, Log.VERBOSE)) {
                        Log.v(TAG, "remote record " + serverSyncId + " is in the deleted table");
                    }
                    final String deletedSyncVersion = deletedCursor.getString(deletedSyncVersionColumn);
                    if (!TextUtils.equals(deletedSyncVersion, serverSyncVersion)) {
                        if (Log.isLoggable(TAG, Log.VERBOSE)) {
                            Log.v(TAG, "setting version of deleted record " + serverSyncId + " to "
                                    + serverSyncVersion);
                        }
                        ContentValues values = new ContentValues();
                        values.put(_SYNC_VERSION, serverSyncVersion);
                        mDb.update(mDeletedTable, values, "_sync_id=?", new String[]{serverSyncId});
                    }
                    continue;
                }

                // If the _sync_local_id is present in the diffsCursor
                // then this record corresponds to a local record that was just
                // inserted into the server and the _sync_local_id is the row id
                // of the local record. Set these fields so that the next check
                // treats this record as an update, which will allow the
                // merger to update the record with the server's sync id
                if (!diffsCursor.isNull(serverSyncLocalIdColumn)) {
                    localRowId = diffsCursor.getLong(serverSyncLocalIdColumn);
                    if (Log.isLoggable(TAG, Log.VERBOSE)) {
                        Log.v(TAG, "the remote record with sync id " + serverSyncId
                                + " has a local sync id, " + localRowId);
                    }
                    localSyncID = serverSyncId;
                    localSyncDirty = false;
                    localSyncVersion = null;
                }

                if (!TextUtils.isEmpty(localSyncID)) {
                    // An existing server item has changed
                    boolean recordChanged = (localSyncVersion == null) ||
                            !serverSyncVersion.equals(localSyncVersion);
                    if (recordChanged) {
                        if (localSyncDirty) {
                            if (Log.isLoggable(TAG, Log.VERBOSE)) {
                                Log.v(TAG, "remote record " + serverSyncId
                                        + " conflicts with local _sync_id " + localSyncID
                                        + ", local _id " + localRowId);
                            }
                            conflict = true;
                        } else {
                            if (Log.isLoggable(TAG, Log.VERBOSE)) {
                                 Log.v(TAG,
                                         "remote record " +
                                                 serverSyncId +
                                         " updates local _sync_id " +
                                         localSyncID + ", local _id " +
                                         localRowId);
                             }
                             update = true;
                        }
                    }
                } else {
                    // the local db doesn't know about this record so add it
                    if (Log.isLoggable(TAG, Log.VERBOSE)) {
                        Log.v(TAG, "remote record " + serverSyncId + " is new, inserting");
                    }
                    insert = true;
                }

                if (update) {
                    updateRow(localRowId, serverDiffs, diffsCursor);
                    syncResult.stats.numUpdates++;
                } else if (conflict) {
                    resolveRow(localRowId, serverSyncId, serverDiffs, diffsCursor);
                    syncResult.stats.numUpdates++;
                } else if (insert) {
                    insertRow(serverDiffs, diffsCursor);
                    syncResult.stats.numInserts++;
                }
            }

            if (Log.isLoggable(TAG, Log.VERBOSE)) {
                Log.v(TAG, "processed " + diffsCount + " server entries");
            }

            // If tombstones aren't in use delete any remaining local rows that
            // don't have corresponding server rows. Keep the rows that don't
            // have a sync id since those were created locally and haven't been
            // synced to the server yet.
            if (!diffsArePartial) {
                while (!localCursor.isAfterLast() && !TextUtils.isEmpty(localCursor.getString(2))) {
                    if (mIsMergeCancelled) {
                        return;
                    }
                    localCount++;
                    final String localSyncId = localCursor.getString(2);
                    if (Log.isLoggable(TAG, Log.VERBOSE)) {
                        Log.v(TAG,
                                "deleting local record " +
                                        localCursor.getLong(1) +
                                        " _sync_id " + localSyncId);
                    }
                    deleteRow(localCursor);
                    if (mDeletedTable != null) {
                        mDb.delete(mDeletedTable, _SYNC_ID + "=?", new String[] {localSyncId});
                    }
                    syncResult.stats.numDeletes++;
                    mDb.yieldIfContended();
                }
            }
            if (Log.isLoggable(TAG, Log.VERBOSE)) Log.v(TAG, "checked " + localCount +
                    " local entries");
        } finally {
            if (diffsCursor != null) diffsCursor.close();
            if (localCursor != null) localCursor.close();
            if (deletedCursor != null) deletedCursor.close();
        }


        if (Log.isLoggable(TAG, Log.VERBOSE)) Log.v(TAG, "applying deletions from the server");

        // Apply deletions from the server
        if (mDeletedTableURL != null) {
            diffsCursor = serverDiffs.query(mDeletedTableURL, null, null, null, null);
            try {
                while (diffsCursor.moveToNext()) {
                    if (mIsMergeCancelled) {
                        return;
                    }
                    // delete all rows that match each element in the diffsCursor
                    fullyDeleteMatchingRows(diffsCursor, account, syncResult);
                    mDb.yieldIfContended();
                }
            } finally {
                diffsCursor.close();
            }
        }
    }

    private void fullyDeleteMatchingRows(Cursor diffsCursor, Account account,
            SyncResult syncResult) {
        int serverSyncIdColumn = diffsCursor.getColumnIndexOrThrow(_SYNC_ID);
        final boolean deleteBySyncId = !diffsCursor.isNull(serverSyncIdColumn);

        // delete the rows explicitly so that the delete operation can be overridden
        final String[] selectionArgs;
        Cursor c = null;
        try {
            if (deleteBySyncId) {
                selectionArgs = new String[]{diffsCursor.getString(serverSyncIdColumn),
                        account.mName, account.mType};
                c = mDb.query(mTable, new String[]{BaseColumns._ID}, SELECT_BY_SYNC_ID_AND_ACCOUNT,
                        selectionArgs, null, null, null);
            } else {
                int serverSyncLocalIdColumn = diffsCursor.getColumnIndexOrThrow(_SYNC_LOCAL_ID);
                selectionArgs = new String[]{diffsCursor.getString(serverSyncLocalIdColumn)};
                c = mDb.query(mTable, new String[]{BaseColumns._ID}, SELECT_BY_ID, selectionArgs,
                        null, null, null);
            }
            c.moveToFirst();
            while (!c.isAfterLast()) {
                deleteRow(c); // advances the cursor
                syncResult.stats.numDeletes++;
            }
        } finally {
          if (c != null) c.close();
        }
        if (deleteBySyncId && mDeletedTable != null) {
            mDb.delete(mDeletedTable, SELECT_BY_SYNC_ID_AND_ACCOUNT, selectionArgs);
        }
    }

    /**
     * Converts cursor into a Map, using the correct types for the values.
     */
    protected void cursorRowToContentValues(Cursor cursor, ContentValues map) {
        DatabaseUtils.cursorRowToContentValues(cursor, map);
    }

    /**
     * Finds local changes, placing the results in the given result object.
     * @param temporaryInstanceFactory As an optimization for the case
     * where there are no client-side diffs, mergeResult may initially
     * have no {@link TempProviderSyncResult#tempContentProvider}.  If this is
     * the first in the sequence of AbstractTableMergers to find
     * client-side diffs, it will use the given ContentProvider to
     * create a temporary instance and store its {@link
     * android.content.ContentProvider} in the mergeResult.
     * @param account
     * @param syncResult
     */
    private void findLocalChanges(TempProviderSyncResult mergeResult,
            SyncableContentProvider temporaryInstanceFactory, Account account,
            SyncResult syncResult) {
        SyncableContentProvider clientDiffs = mergeResult.tempContentProvider;
        if (Log.isLoggable(TAG, Log.VERBOSE)) Log.v(TAG, "generating client updates");

        final String[] accountSelectionArgs = new String[]{account.mName, account.mType};

        // Generate the client updates and insertions
        // Create a cursor for dirty records
        long numInsertsOrUpdates = 0;
        Cursor localChangesCursor = mDb.query(mTable, null, SELECT_UNSYNCED, accountSelectionArgs,
                null, null, null);
        try {
            numInsertsOrUpdates = localChangesCursor.getCount();
            while (localChangesCursor.moveToNext()) {
                if (mIsMergeCancelled) {
                    return;
                }
                if (clientDiffs == null) {
                    clientDiffs = temporaryInstanceFactory.getTemporaryInstance();
                }
                mValues.clear();
                cursorRowToContentValues(localChangesCursor, mValues);
                mValues.remove("_id");
                DatabaseUtils.cursorLongToContentValues(localChangesCursor, "_id", mValues,
                        _SYNC_LOCAL_ID);
                clientDiffs.insert(mTableURL, mValues);
            }
        } finally {
          localChangesCursor.close();
        }

        // Generate the client deletions
        if (Log.isLoggable(TAG, Log.VERBOSE)) Log.v(TAG, "generating client deletions");
        long numEntries = DatabaseUtils.queryNumEntries(mDb, mTable);
        long numDeletedEntries = 0;
        if (mDeletedTable != null) {
            Cursor deletedCursor = mDb.query(mDeletedTable,
                    syncIdAndVersionProjection,
                    _SYNC_ACCOUNT + "=? AND " + _SYNC_ACCOUNT_TYPE + "=? AND "
                            + _SYNC_ID + " IS NOT NULL", accountSelectionArgs,
                    null, null, mDeletedTable + "." + _SYNC_ID);
            try {
                numDeletedEntries = deletedCursor.getCount();
                while (deletedCursor.moveToNext()) {
                    if (mIsMergeCancelled) {
                        return;
                    }
                    if (clientDiffs == null) {
                        clientDiffs = temporaryInstanceFactory.getTemporaryInstance();
                    }
                    mValues.clear();
                    DatabaseUtils.cursorRowToContentValues(deletedCursor, mValues);
                    clientDiffs.insert(mDeletedTableURL, mValues);
                }
            } finally {
                deletedCursor.close();
            }
        }

        if (clientDiffs != null) {
            mergeResult.tempContentProvider = clientDiffs;
        }
        syncResult.stats.numDeletes += numDeletedEntries;
        syncResult.stats.numUpdates += numInsertsOrUpdates;
        syncResult.stats.numEntries += numEntries;
    }
}
