/*
 * 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 com.android.providers.contacts.ContactsDatabaseHelper.AccountsColumns;
import com.android.providers.contacts.ContactsDatabaseHelper.RawContactsColumns;
import com.android.providers.contacts.ContactsDatabaseHelper.Tables;

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 android.util.SparseBooleanArray;
import android.util.SparseLongArray;

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;

    private final long mStartTime = SystemClock.elapsedRealtime();

    private final Object mStatsLock = new Object();
    protected final SparseBooleanArray mAllCallingUids = new SparseBooleanArray();
    protected final SparseLongArray mQueryStats = new SparseLongArray();
    protected final SparseLongArray mBatchStats = new SparseLongArray();
    protected final SparseLongArray mInsertStats = new SparseLongArray();
    protected final SparseLongArray mUpdateStats = new SparseLongArray();
    protected final SparseLongArray mDeleteStats = new SparseLongArray();
    protected final SparseLongArray mInsertInBatchStats = new SparseLongArray();
    protected final SparseLongArray mUpdateInBatchStats = new SparseLongArray();
    protected final SparseLongArray mDeleteInBatchStats = new SparseLongArray();

    private final SparseLongArray mOperationDurationMicroStats = new SparseLongArray();

    private final ThreadLocal<Integer> mOperationNest = ThreadLocal.withInitial(() -> 0);
    private final ThreadLocal<Long> mOperationStartNs = ThreadLocal.withInitial(() -> 0L);

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

    protected final void incrementStats(SparseLongArray stats) {
        final int callingUid = Binder.getCallingUid();
        synchronized (mStatsLock) {
            stats.put(callingUid, stats.get(callingUid) + 1);
            mAllCallingUids.put(callingUid, true);

            final int nest = mOperationNest.get();
            mOperationNest.set(nest + 1);
            if (nest == 0) {
                mOperationStartNs.set(SystemClock.elapsedRealtimeNanos());
            }
        }
    }

    protected final void incrementStats(SparseLongArray statsNonBatch,
            SparseLongArray statsInBatch) {
        final ContactsTransaction t = mTransactionHolder.get();
        final boolean inBatch = t != null && t.isBatch();
        incrementStats(inBatch ? statsInBatch : statsNonBatch);
    }

    protected void finishOperation() {
        final int callingUid = Binder.getCallingUid();
        synchronized (mStatsLock) {
            final int nest = mOperationNest.get();
            mOperationNest.set(nest - 1);
            if (nest == 1) {
                final long duration = SystemClock.elapsedRealtimeNanos() - mOperationStartNs.get();
                mOperationDurationMicroStats.put(callingUid,
                        mOperationDurationMicroStats.get(callingUid) + duration / 1000L);
            }
        }
    }

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

    @Override
    public Uri insert(Uri uri, ContentValues values) {
        incrementStats(mInsertStats, mInsertInBatchStats);
        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 {
            finishOperation();
        }
    }

    @Override
    public int delete(Uri uri, String selection, String[] selectionArgs) {
        incrementStats(mDeleteStats, mDeleteInBatchStats);
        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 {
            finishOperation();
        }
    }

    @Override
    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
        incrementStats(mUpdateStats, mUpdateInBatchStats);
        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 {
            finishOperation();
        }
    }

    @Override
    public int bulkInsert(Uri uri, ContentValues[] values) {
        incrementStats(mBatchStats);
        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 {
            finishOperation();
        }
    }

    @Override
    public ContentProviderResult[] applyBatch(ArrayList<ContentProviderOperation> operations)
            throws OperationApplicationException {
        incrementStats(mBatchStats);
        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 {
            finishOperation();
        }
    }

    /**
     * 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);

        pw.print("  Uptime: ");
        pw.print((SystemClock.elapsedRealtime() - mStartTime) / (60 * 1000));
        pw.println(" minutes");

        synchronized (mStatsLock) {
            pw.println();
            pw.println("  Client activities:");
            pw.println("    UID        Query  Insert Update Delete   Batch Insert Update Delete"
                + "          Sec");
            for (int i = 0; i < mAllCallingUids.size(); i++) {
                final int uid = mAllCallingUids.keyAt(i);
                pw.println(String.format(
                        "    %-9d %6d  %6d %6d %6d  %6d %6d %6d %6d %12.3f",
                        uid,
                        mQueryStats.get(uid),
                        mInsertStats.get(uid),
                        mUpdateStats.get(uid),
                        mDeleteStats.get(uid),
                        mBatchStats.get(uid),
                        mInsertInBatchStats.get(uid),
                        mUpdateInBatchStats.get(uid),
                        mDeleteInBatchStats.get(uid),
                        (mOperationDurationMicroStats.get(uid) / 1000000.0)
                ));
            }
        }

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