/*
 * 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_ACCOUNT + " IS NULL OR ("
                + _SYNC_ACCOUNT + "=? and " + _SYNC_ACCOUNT_TYPE + "=?)) and "
            + "(" + _SYNC_ID + " IS NULL OR (" + _SYNC_DIRTY + " > 0 and "
                                              + _SYNC_VERSION + " IS NOT 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.name, account.type};
            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
                    // If serverSyncVersion is null, there is no edit URL;
                    // server won't let this change be written.
                    boolean recordChanged = (localSyncVersion == null) ||
                            (serverSyncVersion == 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 {
                        if (Log.isLoggable(TAG, Log.VERBOSE)) {
                            Log.v(TAG,
                                    "Skipping update: localSyncVersion: " + localSyncVersion +
                                    ", serverSyncVersion: " + serverSyncVersion);
                        }
                    }
                } 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.name, account.type};
                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.name, account.type};

        // 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;
    }
}
