/*
 * Copyright (C) 2011 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.providers.contacts;

import android.content.ContentProvider;
import android.content.ContentProviderOperation;
import android.content.ContentProviderResult;
import android.content.ContentValues;
import android.content.Context;
import android.content.OperationApplicationException;
import android.database.Cursor;
import android.database.DatabaseUtils;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteTransactionListener;
import android.net.Uri;
import android.os.Binder;
import android.os.SystemClock;
import android.provider.BaseColumns;
import android.provider.ContactsContract.Data;
import android.provider.ContactsContract.RawContacts;
import android.util.Log;

import com.android.internal.util.ProviderAccessStats;
import com.android.providers.contacts.ContactsDatabaseHelper.AccountsColumns;
import com.android.providers.contacts.ContactsDatabaseHelper.RawContactsColumns;
import com.android.providers.contacts.ContactsDatabaseHelper.Tables;

import java.io.PrintWriter;
import java.util.ArrayList;

/**
 * A common base class for the contacts and profile providers.  This handles much of the same
 * logic that SQLiteContentProvider does (i.e. starting transactions on the appropriate database),
 * but exposes awareness of batch operations to the subclass so that cross-database operations
 * can be supported.
 */
public abstract class AbstractContactsProvider extends ContentProvider
        implements SQLiteTransactionListener {

    public static final String TAG = "ContactsProvider";

    public static final boolean VERBOSE_LOGGING = Log.isLoggable(TAG, Log.VERBOSE);

    /** Set true to enable detailed transaction logging. */
    public static final boolean ENABLE_TRANSACTION_LOG = false; // Don't submit with true.

    /**
     * Duration in ms to sleep after successfully yielding the lock during a batch operation.
     */
    protected static final int SLEEP_AFTER_YIELD_DELAY = 4000;

    /**
     * Maximum number of operations allowed in a batch between yield points.
     */
    private static final int MAX_OPERATIONS_PER_YIELD_POINT = 500;

    /**
     * Number of inserts performed in bulk to allow before yielding the transaction.
     */
    private static final int BULK_INSERTS_PER_YIELD_POINT = 50;

    /**
     * The contacts transaction that is active in this thread.
     */
    private ThreadLocal<ContactsTransaction> mTransactionHolder;

    /**
     * The DB helper to use for this content provider.
     */
    private ContactsDatabaseHelper mDbHelper;

    /**
     * The database helper to serialize all transactions on.  If non-null, any new transaction
     * created by this provider will automatically retrieve a writable database from this helper
     * and initiate a transaction on that database.  This should be used to ensure that operations
     * across multiple databases are all blocked on a single DB lock (to prevent deadlock cases).
     *
     * Hint: It's always {@link ContactsDatabaseHelper}.
     *
     * TODO Change the structure to make it obvious that it's actually always set, and is the
     * {@link ContactsDatabaseHelper}.
     */
    private SQLiteOpenHelper mSerializeOnDbHelper;

    /**
     * The tag corresponding to the database used for serializing transactions.
     *
     * Hint: It's always the contacts db helper tag.
     *
     * See also the TODO on {@link #mSerializeOnDbHelper}.
     */
    private String mSerializeDbTag;

    /**
     * The transaction listener used with {@link #mSerializeOnDbHelper}.
     *
     * Hint: It's always {@link ContactsProvider2}.
     *
     * See also the TODO on {@link #mSerializeOnDbHelper}.
     */
    private SQLiteTransactionListener mSerializedDbTransactionListener;


    protected final ProviderAccessStats mStats = new ProviderAccessStats();

    @Override
    public boolean onCreate() {
        Context context = getContext();
        mDbHelper = newDatabaseHelper(context);
        mTransactionHolder = getTransactionHolder();
        return true;
    }

    public ContactsDatabaseHelper getDatabaseHelper() {
        return mDbHelper;
    }

    /**
     * Specifies a database helper (and corresponding tag) to serialize all transactions on.
     *
     * See also the TODO on {@link #mSerializeOnDbHelper}.
     */
    public void setDbHelperToSerializeOn(SQLiteOpenHelper serializeOnDbHelper, String tag,
            SQLiteTransactionListener listener) {
        mSerializeOnDbHelper = serializeOnDbHelper;
        mSerializeDbTag = tag;
        mSerializedDbTransactionListener = listener;
    }

    public ContactsTransaction getCurrentTransaction() {
        return mTransactionHolder.get();
    }

    private boolean isInBatch() {
        final ContactsTransaction t = mTransactionHolder.get();
        return t != null && t.isBatch();
    }

    @Override
    public Uri insert(Uri uri, ContentValues values) {
        final int callingUid = Binder.getCallingUid();
        mStats.incrementInsertStats(callingUid, isInBatch());
        try {
            ContactsTransaction transaction = startTransaction(false);
            try {
                Uri result = insertInTransaction(uri, values);
                if (result != null) {
                    transaction.markDirty();
                }
                transaction.markSuccessful(false);
                return result;
            } finally {
                endTransaction(false);
            }
        } finally {
            mStats.finishOperation(callingUid);
        }
    }

    @Override
    public int delete(Uri uri, String selection, String[] selectionArgs) {
        final int callingUid = Binder.getCallingUid();
        mStats.incrementDeleteStats(callingUid, isInBatch());
        try {
            ContactsTransaction transaction = startTransaction(false);
            try {
                int deleted = deleteInTransaction(uri, selection, selectionArgs);
                if (deleted > 0) {
                    transaction.markDirty();
                }
                transaction.markSuccessful(false);
                return deleted;
            } finally {
                endTransaction(false);
            }
        } finally {
            mStats.finishOperation(callingUid);
        }
    }

    @Override
    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
        final int callingUid = Binder.getCallingUid();
        mStats.incrementUpdateStats(callingUid, isInBatch());
        try {
            ContactsTransaction transaction = startTransaction(false);
            try {
                int updated = updateInTransaction(uri, values, selection, selectionArgs);
                if (updated > 0) {
                    transaction.markDirty();
                }
                transaction.markSuccessful(false);
                return updated;
            } finally {
                endTransaction(false);
            }
        } finally {
            mStats.finishOperation(callingUid);
        }
    }

    @Override
    public int bulkInsert(Uri uri, ContentValues[] values) {
        final int callingUid = Binder.getCallingUid();
        mStats.incrementBatchStats(callingUid);
        try {
            ContactsTransaction transaction = startTransaction(true);
            int numValues = values.length;
            int opCount = 0;
            try {
                for (int i = 0; i < numValues; i++) {
                    insert(uri, values[i]);
                    if (++opCount >= BULK_INSERTS_PER_YIELD_POINT) {
                        opCount = 0;
                        try {
                            yield(transaction);
                        } catch (RuntimeException re) {
                            transaction.markYieldFailed();
                            throw re;
                        }
                    }
                }
                transaction.markSuccessful(true);
            } finally {
                endTransaction(true);
            }
            return numValues;
        } finally {
            mStats.finishOperation(callingUid);
        }
    }

    @Override
    public ContentProviderResult[] applyBatch(ArrayList<ContentProviderOperation> operations)
            throws OperationApplicationException {
        final int callingUid = Binder.getCallingUid();
        mStats.incrementBatchStats(callingUid);
        try {
            if (VERBOSE_LOGGING) {
                Log.v(TAG, "applyBatch: " + operations.size() + " ops");
            }
            int ypCount = 0;
            int opCount = 0;
            ContactsTransaction transaction = startTransaction(true);
            try {
                final int numOperations = operations.size();
                final ContentProviderResult[] results = new ContentProviderResult[numOperations];
                for (int i = 0; i < numOperations; i++) {
                    if (++opCount >= MAX_OPERATIONS_PER_YIELD_POINT) {
                        throw new OperationApplicationException(
                                "Too many content provider operations between yield points. "
                                        + "The maximum number of operations per yield point is "
                                        + MAX_OPERATIONS_PER_YIELD_POINT, ypCount);
                    }
                    final ContentProviderOperation operation = operations.get(i);
                    if (i > 0 && operation.isYieldAllowed()) {
                        if (VERBOSE_LOGGING) {
                            Log.v(TAG, "applyBatch: " + opCount + " ops finished; about to yield...");
                        }
                        opCount = 0;
                        try {
                            if (yield(transaction)) {
                                ypCount++;
                            }
                        } catch (RuntimeException re) {
                            transaction.markYieldFailed();
                            throw re;
                        }
                    }

                    results[i] = operation.apply(this, results, i);
                }
                transaction.markSuccessful(true);
                return results;
            } finally {
                endTransaction(true);
            }
        } finally {
            mStats.finishOperation(callingUid);
        }
    }

    /**
     * If we are not yet already in a transaction, this starts one (on the DB to serialize on, if
     * present) and sets the thread-local transaction variable for tracking.  If we are already in
     * a transaction, this returns that transaction, and the batch parameter is ignored.
     * @param callerIsBatch Whether the caller is operating in batch mode.
     */
    private ContactsTransaction startTransaction(boolean callerIsBatch) {
        if (ENABLE_TRANSACTION_LOG) {
            Log.i(TAG, "startTransaction " + getClass().getSimpleName() +
                    "  callerIsBatch=" + callerIsBatch, new RuntimeException("startTransaction"));
        }
        ContactsTransaction transaction = mTransactionHolder.get();
        if (transaction == null) {
            transaction = new ContactsTransaction(callerIsBatch);
            if (mSerializeOnDbHelper != null) {
                transaction.startTransactionForDb(mSerializeOnDbHelper.getWritableDatabase(),
                        mSerializeDbTag, mSerializedDbTransactionListener);
            }
            mTransactionHolder.set(transaction);
        }
        return transaction;
    }

    /**
     * Ends the current transaction and clears out the member variable.  This does not set the
     * transaction as being successful.
     * @param callerIsBatch Whether the caller is operating in batch mode.
     */
    private void endTransaction(boolean callerIsBatch) {
        if (ENABLE_TRANSACTION_LOG) {
            Log.i(TAG, "endTransaction " + getClass().getSimpleName() +
                    "  callerIsBatch=" + callerIsBatch, new RuntimeException("endTransaction"));
        }
        ContactsTransaction transaction = mTransactionHolder.get();
        if (transaction != null && (!transaction.isBatch() || callerIsBatch)) {
            boolean notify = false;
            try {
                if (transaction.isDirty()) {
                    notify = true;
                }
                transaction.finish(callerIsBatch);
                if (notify) {
                    notifyChange();
                }
            } finally {
                // No matter what, make sure we clear out the thread-local transaction reference.
                mTransactionHolder.set(null);
            }
        }
    }

    /**
     * Gets the database helper for this contacts provider.  This is called once, during onCreate().
     * Do not call in other places.
     */
    protected abstract ContactsDatabaseHelper newDatabaseHelper(Context context);

    /**
     * Gets the thread-local transaction holder to use for keeping track of the transaction.  This
     * is called once, in onCreate().  If multiple classes are inheriting from this class that need
     * to be kept in sync on the same transaction, they must all return the same thread-local.
     */
    protected abstract ThreadLocal<ContactsTransaction> getTransactionHolder();

    protected abstract Uri insertInTransaction(Uri uri, ContentValues values);

    protected abstract int deleteInTransaction(Uri uri, String selection, String[] selectionArgs);

    protected abstract int updateInTransaction(Uri uri, ContentValues values, String selection,
            String[] selectionArgs);

    protected abstract boolean yield(ContactsTransaction transaction);

    protected abstract void notifyChange();

    private static final String ACCOUNTS_QUERY =
            "SELECT * FROM " + Tables.ACCOUNTS + " ORDER BY " + BaseColumns._ID;

    private static final String NUM_INVISIBLE_CONTACTS_QUERY =
            "SELECT count(*) FROM " + Tables.CONTACTS;

    private static final String NUM_VISIBLE_CONTACTS_QUERY =
            "SELECT count(*) FROM " + Tables.DEFAULT_DIRECTORY;

    private static final String NUM_RAW_CONTACTS_PER_CONTACT =
            "SELECT _id, count(*) as c FROM " + Tables.RAW_CONTACTS
                    + " GROUP BY " + RawContacts.CONTACT_ID;

    private static final String MAX_RAW_CONTACTS_PER_CONTACT =
            "SELECT max(c) FROM (" + NUM_RAW_CONTACTS_PER_CONTACT + ")";

    private static final String AVG_RAW_CONTACTS_PER_CONTACT =
            "SELECT avg(c) FROM (" + NUM_RAW_CONTACTS_PER_CONTACT + ")";

    private static final String NUM_RAW_CONTACT_PER_ACCOUNT_PER_CONTACT =
            "SELECT " + RawContactsColumns.ACCOUNT_ID + " AS aid"
                    + ", " + RawContacts.CONTACT_ID + " AS cid"
                    + ", count(*) AS c"
                    + " FROM " + Tables.RAW_CONTACTS
                    + " GROUP BY aid, cid";

    private static final String RAW_CONTACTS_PER_ACCOUNT_PER_CONTACT =
            "SELECT aid, sum(c) AS s, max(c) AS m, avg(c) AS a"
                    + " FROM (" + NUM_RAW_CONTACT_PER_ACCOUNT_PER_CONTACT + ")"
                    + " GROUP BY aid";

    private static final String DATA_WITH_ACCOUNT =
            "SELECT d._id AS did"
            + ", d." + Data.RAW_CONTACT_ID + " AS rid"
            + ", r." + RawContactsColumns.ACCOUNT_ID + " AS aid"
            + " FROM " + Tables.DATA + " AS d JOIN " + Tables.RAW_CONTACTS + " AS r"
            + " ON d." + Data.RAW_CONTACT_ID + "=r._id";

    private static final String NUM_DATA_PER_ACCOUNT_PER_RAW_CONTACT =
            "SELECT aid, rid, count(*) AS c"
                    + " FROM (" + DATA_WITH_ACCOUNT + ")"
                    + " GROUP BY aid, rid";

    private static final String DATA_PER_ACCOUNT_PER_RAW_CONTACT =
            "SELECT aid, sum(c) AS s, max(c) AS m, avg(c) AS a"
                    + " FROM (" + NUM_DATA_PER_ACCOUNT_PER_RAW_CONTACT + ")"
                    + " GROUP BY aid";

    protected void dump(PrintWriter pw, String dbName) {
        pw.print("Database: ");
        pw.println(dbName);

        mStats.dump(pw, "  ");

        if (mDbHelper == null) {
            pw.println("mDbHelper is null");
            return;
        }
        try {
            pw.println();
            pw.println("  Accounts:");
            final SQLiteDatabase db = mDbHelper.getReadableDatabase();

            try (Cursor c = db.rawQuery(ACCOUNTS_QUERY, null)) {
                c.moveToPosition(-1);
                while (c.moveToNext()) {
                    pw.print("    ");
                    dumpLongColumn(pw, c, BaseColumns._ID);
                    pw.print(" ");
                    dumpStringColumn(pw, c, AccountsColumns.ACCOUNT_NAME);
                    pw.print(" ");
                    dumpStringColumn(pw, c, AccountsColumns.ACCOUNT_TYPE);
                    pw.print(" ");
                    dumpStringColumn(pw, c, AccountsColumns.DATA_SET);
                    pw.println();
                }
            }

            pw.println();
            pw.println("  Contacts:");
            pw.print("    # of visible: ");
            pw.print(longForQuery(db, NUM_VISIBLE_CONTACTS_QUERY));
            pw.println();

            pw.print("    # of invisible: ");
            pw.print(longForQuery(db, NUM_INVISIBLE_CONTACTS_QUERY));
            pw.println();

            pw.print("    Max # of raw contacts: ");
            pw.print(longForQuery(db, MAX_RAW_CONTACTS_PER_CONTACT));
            pw.println();

            pw.print("    Avg # of raw contacts: ");
            pw.print(doubleForQuery(db, AVG_RAW_CONTACTS_PER_CONTACT));
            pw.println();

            pw.println();
            pw.println("  Raw contacts (per account):");
            try (Cursor c = db.rawQuery(RAW_CONTACTS_PER_ACCOUNT_PER_CONTACT, null)) {
                c.moveToPosition(-1);
                while (c.moveToNext()) {
                    pw.print("    ");
                    dumpLongColumn(pw, c, "aid");
                    pw.print(" total # of raw contacts: ");
                    dumpStringColumn(pw, c, "s");
                    pw.print(", max # per contact: ");
                    dumpLongColumn(pw, c, "m");
                    pw.print(", avg # per contact: ");
                    dumpDoubleColumn(pw, c, "a");
                    pw.println();
                }
            }

            pw.println();
            pw.println("  Data (per account):");
            try (Cursor c = db.rawQuery(DATA_PER_ACCOUNT_PER_RAW_CONTACT, null)) {
                c.moveToPosition(-1);
                while (c.moveToNext()) {
                    pw.print("    ");
                    dumpLongColumn(pw, c, "aid");
                    pw.print(" total # of data:");
                    dumpLongColumn(pw, c, "s");
                    pw.print(", max # per raw contact: ");
                    dumpLongColumn(pw, c, "m");
                    pw.print(", avg # per raw contact: ");
                    dumpDoubleColumn(pw, c, "a");
                    pw.println();
                }
            }
        } catch (Exception e) {
            pw.println("Error: " + e);
        }
    }

    private static void dumpStringColumn(PrintWriter pw, Cursor c, String column) {
        final int index = c.getColumnIndex(column);
        if (index == -1) {
            pw.println("Column not found: " + column);
            return;
        }
        final String value = c.getString(index);
        if (value == null) {
            pw.print("(null)");
        } else if (value.length() == 0) {
            pw.print("\"\"");
        } else {
            pw.print(value);
        }
    }

    private static void dumpLongColumn(PrintWriter pw, Cursor c, String column) {
        final int index = c.getColumnIndex(column);
        if (index == -1) {
            pw.println("Column not found: " + column);
            return;
        }
        if (c.isNull(index)) {
            pw.print("(null)");
        } else {
            pw.print(c.getLong(index));
        }
    }

    private static void dumpDoubleColumn(PrintWriter pw, Cursor c, String column) {
        final int index = c.getColumnIndex(column);
        if (index == -1) {
            pw.println("Column not found: " + column);
            return;
        }
        if (c.isNull(index)) {
            pw.print("(null)");
        } else {
            pw.print(c.getDouble(index));
        }
    }

    private static long longForQuery(SQLiteDatabase db, String query) {
        return DatabaseUtils.longForQuery(db, query, null);
    }

    private static double doubleForQuery(SQLiteDatabase db, String query) {
        try (final Cursor c = db.rawQuery(query, null)) {
            if (!c.moveToFirst()) {
                return -1;
            }
            return c.getDouble(0);
        }
    }
}
