/*
 * Copyright (C) 2015 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.annotation.Nullable;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.DatabaseUtils;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.provider.CallLog.Calls;
import android.provider.VoicemailContract;
import android.provider.VoicemailContract.Status;
import android.provider.VoicemailContract.Voicemails;
import android.text.TextUtils;
import android.util.ArraySet;
import android.util.Log;

import com.android.internal.annotations.VisibleForTesting;
import com.android.providers.contacts.util.PropertyUtils;

/**
 * SQLite database (helper) for {@link CallLogProvider} and {@link VoicemailContentProvider}.
 */
public class CallLogDatabaseHelper {
    private static final String TAG = "CallLogDatabaseHelper";

    private static final int DATABASE_VERSION = 9;

    private static final boolean DEBUG = false; // DON'T SUBMIT WITH TRUE

    private static final String DATABASE_NAME = "calllog.db";

    private static final String SHADOW_DATABASE_NAME = "calllog_shadow.db";

    private static final int IDLE_CONNECTION_TIMEOUT_MS = 30000;

    private static CallLogDatabaseHelper sInstance;

    /** Instance for the "shadow" provider. */
    private static CallLogDatabaseHelper sInstanceForShadow;

    private final Context mContext;

    private final OpenHelper mOpenHelper;

    public interface Tables {
        String CALLS = "calls";
        String VOICEMAIL_STATUS = "voicemail_status";
    }

    public interface DbProperties {
        String CALL_LOG_LAST_SYNCED = "call_log_last_synced";
        String CALL_LOG_LAST_SYNCED_FOR_SHADOW = "call_log_last_synced_for_shadow";
        String DATA_MIGRATED = "migrated";
    }

    /**
     * Constants used in the contacts DB helper, which are needed for migration.
     *
     * DO NOT CHANCE ANY OF THE CONSTANTS.
     */
    private interface LegacyConstants {
        /** Table name used in the contacts DB.*/
        String CALLS_LEGACY = "calls";

        /** Table name used in the contacts DB.*/
        String VOICEMAIL_STATUS_LEGACY = "voicemail_status";

        /** Prop name used in the contacts DB.*/
        String CALL_LOG_LAST_SYNCED_LEGACY = "call_log_last_synced";
    }

    private final class OpenHelper extends SQLiteOpenHelper {
        public OpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory,
                int version) {
            super(context, name, factory, version);
            // Memory optimization - close idle connections after 30s of inactivity
            setIdleConnectionTimeout(IDLE_CONNECTION_TIMEOUT_MS);
        }

        @Override
        public void onCreate(SQLiteDatabase db) {
            if (DEBUG) {
                Log.d(TAG, "onCreate");
            }

            PropertyUtils.createPropertiesTable(db);

            // *** NOTE ABOUT CHANGING THE DB SCHEMA ***
            //
            // The CALLS and VOICEMAIL_STATUS table used to be in the contacts2.db.  So we need to
            // migrate from these legacy tables, if exist, after creating the calllog DB, which is
            // done in migrateFromLegacyTables().
            //
            // This migration is slightly different from a regular upgrade step, because it's always
            // performed from the legacy schema (of the latest version -- because the migration
            // source is always the latest DB after all the upgrade steps) to the *latest* schema
            // at once.
            //
            // This means certain kind of changes are not doable without changing the
            // migration logic.  For example, if you rename a column in the DB, the migration step
            // will need to be updated to handle the column name change.

            db.execSQL("CREATE TABLE " + Tables.CALLS + " (" +
                    Calls._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," +
                    Calls.NUMBER + " TEXT," +
                    Calls.NUMBER_PRESENTATION + " INTEGER NOT NULL DEFAULT " +
                    Calls.PRESENTATION_ALLOWED + "," +
                    Calls.POST_DIAL_DIGITS + " TEXT NOT NULL DEFAULT ''," +
                    Calls.VIA_NUMBER + " TEXT NOT NULL DEFAULT ''," +
                    Calls.DATE + " INTEGER," +
                    Calls.DURATION + " INTEGER," +
                    Calls.DATA_USAGE + " INTEGER," +
                    Calls.TYPE + " INTEGER," +
                    Calls.FEATURES + " INTEGER NOT NULL DEFAULT 0," +
                    Calls.PHONE_ACCOUNT_COMPONENT_NAME + " TEXT," +
                    Calls.PHONE_ACCOUNT_ID + " TEXT," +
                    Calls.PHONE_ACCOUNT_ADDRESS + " TEXT," +
                    Calls.PHONE_ACCOUNT_HIDDEN + " INTEGER NOT NULL DEFAULT 0," +
                    Calls.SUB_ID + " INTEGER DEFAULT -1," +
                    Calls.NEW + " INTEGER," +
                    Calls.CACHED_NAME + " TEXT," +
                    Calls.CACHED_NUMBER_TYPE + " INTEGER," +
                    Calls.CACHED_NUMBER_LABEL + " TEXT," +
                    Calls.COUNTRY_ISO + " TEXT," +
                    Calls.VOICEMAIL_URI + " TEXT," +
                    Calls.IS_READ + " INTEGER," +
                    Calls.GEOCODED_LOCATION + " TEXT," +
                    Calls.CACHED_LOOKUP_URI + " TEXT," +
                    Calls.CACHED_MATCHED_NUMBER + " TEXT," +
                    Calls.CACHED_NORMALIZED_NUMBER + " TEXT," +
                    Calls.CACHED_PHOTO_ID + " INTEGER NOT NULL DEFAULT 0," +
                    Calls.CACHED_PHOTO_URI + " TEXT," +
                    Calls.CACHED_FORMATTED_NUMBER + " TEXT," +
                    Calls.ADD_FOR_ALL_USERS + " INTEGER NOT NULL DEFAULT 1," +
                    Calls.LAST_MODIFIED + " INTEGER DEFAULT 0," +
                    Calls.CALL_SCREENING_COMPONENT_NAME + " TEXT," +
                    Calls.CALL_SCREENING_APP_NAME + " TEXT," +
                    Calls.BLOCK_REASON + " INTEGER NOT NULL DEFAULT 0," +
                    Calls.MISSED_REASON + " INTEGER NOT NULL DEFAULT 0," +

                    Voicemails._DATA + " TEXT," +
                    Voicemails.HAS_CONTENT + " INTEGER," +
                    Voicemails.MIME_TYPE + " TEXT," +
                    Voicemails.SOURCE_DATA + " TEXT," +
                    Voicemails.SOURCE_PACKAGE + " TEXT," +
                    Voicemails.TRANSCRIPTION + " TEXT," +
                    Voicemails.TRANSCRIPTION_STATE + " INTEGER NOT NULL DEFAULT 0," +
                    Voicemails.STATE + " INTEGER," +
                    Voicemails.DIRTY + " INTEGER NOT NULL DEFAULT 0," +
                    Voicemails.DELETED + " INTEGER NOT NULL DEFAULT 0," +
                    Voicemails.BACKED_UP + " INTEGER NOT NULL DEFAULT 0," +
                    Voicemails.RESTORED + " INTEGER NOT NULL DEFAULT 0," +
                    Voicemails.ARCHIVED + " INTEGER NOT NULL DEFAULT 0," +
                    Voicemails.IS_OMTP_VOICEMAIL + " INTEGER NOT NULL DEFAULT 0" +
                    ");");

            db.execSQL("CREATE TABLE " + Tables.VOICEMAIL_STATUS + " (" +
                    VoicemailContract.Status._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," +
                    VoicemailContract.Status.SOURCE_PACKAGE + " TEXT NOT NULL," +
                    VoicemailContract.Status.PHONE_ACCOUNT_COMPONENT_NAME + " TEXT," +
                    VoicemailContract.Status.PHONE_ACCOUNT_ID + " TEXT," +
                    VoicemailContract.Status.SETTINGS_URI + " TEXT," +
                    VoicemailContract.Status.VOICEMAIL_ACCESS_URI + " TEXT," +
                    VoicemailContract.Status.CONFIGURATION_STATE + " INTEGER," +
                    VoicemailContract.Status.DATA_CHANNEL_STATE + " INTEGER," +
                    VoicemailContract.Status.NOTIFICATION_CHANNEL_STATE + " INTEGER," +
                    VoicemailContract.Status.QUOTA_OCCUPIED + " INTEGER DEFAULT -1," +
                    VoicemailContract.Status.QUOTA_TOTAL + " INTEGER DEFAULT -1," +
                    VoicemailContract.Status.SOURCE_TYPE + " TEXT" +
                    ");");

            migrateFromLegacyTables(db);
        }

        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
            if (DEBUG) {
                Log.d(TAG, "onUpgrade");
            }

            if (oldVersion < 2) {
                upgradeToVersion2(db);
            }

            if (oldVersion < 3) {
                upgradeToVersion3(db);
            }

            if (oldVersion < 4) {
                upgradeToVersion4(db);
            }

            if (oldVersion < 5) {
                upgradeToVersion5(db);
            }

            if (oldVersion < 6) {
                upgradeToVersion6(db);
            }

            if (oldVersion < 7) {
                upgradeToVersion7(db);
            }

            if (oldVersion < 8) {
                upgradetoVersion8(db);
            }

            if (oldVersion < 9) {
                upgradeToVersion9(db);
            }
        }
    }

    @VisibleForTesting
    CallLogDatabaseHelper(Context context, String databaseName) {
        mContext = context;
        mOpenHelper = new OpenHelper(mContext, databaseName, /* factory=*/ null, DATABASE_VERSION);
    }

    public static synchronized CallLogDatabaseHelper getInstance(Context context) {
        if (sInstance == null) {
            sInstance = new CallLogDatabaseHelper(context, DATABASE_NAME);
        }
        return sInstance;
    }

    public static synchronized CallLogDatabaseHelper getInstanceForShadow(Context context) {
        if (sInstanceForShadow == null) {
            // Shadow provider is always encryption-aware.
            sInstanceForShadow = new CallLogDatabaseHelper(
                    context.createDeviceProtectedStorageContext(), SHADOW_DATABASE_NAME);
        }
        return sInstanceForShadow;
    }

    public SQLiteDatabase getReadableDatabase() {
        return mOpenHelper.getReadableDatabase();
    }

    public SQLiteDatabase getWritableDatabase() {
        return mOpenHelper.getWritableDatabase();
    }

    public String getProperty(String key, String defaultValue) {
        return PropertyUtils.getProperty(getReadableDatabase(), key, defaultValue);
    }

    public void setProperty(String key, String value) {
        PropertyUtils.setProperty(getWritableDatabase(), key, value);
    }

    /**
     * Add the {@link Calls.VIA_NUMBER} Column to the CallLog Database.
     */
    private void upgradeToVersion2(SQLiteDatabase db) {
        db.execSQL("ALTER TABLE " + Tables.CALLS + " ADD " + Calls.VIA_NUMBER +
                " TEXT NOT NULL DEFAULT ''");
    }

    /**
     * Add the {@link Status.SOURCE_TYPE} Column to the VoicemailStatus Database.
     */
    private void upgradeToVersion3(SQLiteDatabase db) {
        db.execSQL("ALTER TABLE " + Tables.VOICEMAIL_STATUS + " ADD " + Status.SOURCE_TYPE +
                " TEXT");
    }

    /**
     * Add {@link Voicemails.BACKED_UP} {@link Voicemails.ARCHIVE} {@link
     * Voicemails.IS_OMTP_VOICEMAIL} column to the CallLog database.
     */
    private void upgradeToVersion4(SQLiteDatabase db) {
        db.execSQL("ALTER TABLE calls ADD backed_up INTEGER NOT NULL DEFAULT 0");
        db.execSQL("ALTER TABLE calls ADD restored INTEGER NOT NULL DEFAULT 0");
        db.execSQL("ALTER TABLE calls ADD archived INTEGER NOT NULL DEFAULT 0");
        db.execSQL("ALTER TABLE calls ADD is_omtp_voicemail INTEGER NOT NULL DEFAULT 0");
    }

    /**
     * Add {@link Voicemails.TRANSCRIPTION_STATE} column to the CallLog database.
     */
    private void upgradeToVersion5(SQLiteDatabase db) {
        db.execSQL("ALTER TABLE calls ADD transcription_state INTEGER NOT NULL DEFAULT 0");
    }

    /**
     * Add {@link CallLog.Calls#CALL_SCREENING_COMPONENT_NAME}
     * {@link CallLog.Calls#CALL_SCREENING_APP_NAME}
     * {@link CallLog.Calls#BLOCK_REASON} column to the CallLog database.
     */
    private void upgradeToVersion6(SQLiteDatabase db) {
        db.execSQL("ALTER TABLE calls ADD call_screening_component_name TEXT");
        db.execSQL("ALTER TABLE calls ADD call_screening_app_name TEXT");
        db.execSQL("ALTER TABLE calls ADD block_reason INTEGER NOT NULL DEFAULT 0");
    }

    /**
     * Add {@code android.telecom.CallIdentification} columns; these are destined to be removed
     * in {@link #upgradetoVersion8(SQLiteDatabase)}.
     * @param db DB to upgrade
     */
    private void upgradeToVersion7(SQLiteDatabase db) {
        db.execSQL("ALTER TABLE calls ADD call_id_package_name TEXT NULL");
        db.execSQL("ALTER TABLE calls ADD call_id_app_name TEXT NULL");
        db.execSQL("ALTER TABLE calls ADD call_id_name TEXT NULL");
        db.execSQL("ALTER TABLE calls ADD call_id_description TEXT NULL");
        db.execSQL("ALTER TABLE calls ADD call_id_details TEXT NULL");
        db.execSQL("ALTER TABLE calls ADD call_id_nuisance_confidence INTEGER NULL");
    }

    /**
     * Remove the {@code android.telecom.CallIdentification} column.
     * @param db DB to upgrade
     */
    private void upgradetoVersion8(SQLiteDatabase db) {
        db.beginTransaction();
        try {
            String oldTable = Tables.CALLS + "_old";
            // SQLite3 doesn't support altering a column name, so we'll rename the old calls table..
            db.execSQL("ALTER TABLE calls RENAME TO " + oldTable);

            // ... create a new one (yes, this seems similar to what is in onCreate, but we can't
            // assume that one won't change in the future) ...
            db.execSQL("CREATE TABLE " + Tables.CALLS + " (" +
                    Calls._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," +
                    Calls.NUMBER + " TEXT," +
                    Calls.NUMBER_PRESENTATION + " INTEGER NOT NULL DEFAULT " +
                    Calls.PRESENTATION_ALLOWED + "," +
                    Calls.POST_DIAL_DIGITS + " TEXT NOT NULL DEFAULT ''," +
                    Calls.VIA_NUMBER + " TEXT NOT NULL DEFAULT ''," +
                    Calls.DATE + " INTEGER," +
                    Calls.DURATION + " INTEGER," +
                    Calls.DATA_USAGE + " INTEGER," +
                    Calls.TYPE + " INTEGER," +
                    Calls.FEATURES + " INTEGER NOT NULL DEFAULT 0," +
                    Calls.PHONE_ACCOUNT_COMPONENT_NAME + " TEXT," +
                    Calls.PHONE_ACCOUNT_ID + " TEXT," +
                    Calls.PHONE_ACCOUNT_ADDRESS + " TEXT," +
                    Calls.PHONE_ACCOUNT_HIDDEN + " INTEGER NOT NULL DEFAULT 0," +
                    Calls.SUB_ID + " INTEGER DEFAULT -1," +
                    Calls.NEW + " INTEGER," +
                    Calls.CACHED_NAME + " TEXT," +
                    Calls.CACHED_NUMBER_TYPE + " INTEGER," +
                    Calls.CACHED_NUMBER_LABEL + " TEXT," +
                    Calls.COUNTRY_ISO + " TEXT," +
                    Calls.VOICEMAIL_URI + " TEXT," +
                    Calls.IS_READ + " INTEGER," +
                    Calls.GEOCODED_LOCATION + " TEXT," +
                    Calls.CACHED_LOOKUP_URI + " TEXT," +
                    Calls.CACHED_MATCHED_NUMBER + " TEXT," +
                    Calls.CACHED_NORMALIZED_NUMBER + " TEXT," +
                    Calls.CACHED_PHOTO_ID + " INTEGER NOT NULL DEFAULT 0," +
                    Calls.CACHED_PHOTO_URI + " TEXT," +
                    Calls.CACHED_FORMATTED_NUMBER + " TEXT," +
                    Calls.ADD_FOR_ALL_USERS + " INTEGER NOT NULL DEFAULT 1," +
                    Calls.LAST_MODIFIED + " INTEGER DEFAULT 0," +
                    Calls.CALL_SCREENING_COMPONENT_NAME + " TEXT," +
                    Calls.CALL_SCREENING_APP_NAME + " TEXT," +
                    Calls.BLOCK_REASON + " INTEGER NOT NULL DEFAULT 0," +

                    Voicemails._DATA + " TEXT," +
                    Voicemails.HAS_CONTENT + " INTEGER," +
                    Voicemails.MIME_TYPE + " TEXT," +
                    Voicemails.SOURCE_DATA + " TEXT," +
                    Voicemails.SOURCE_PACKAGE + " TEXT," +
                    Voicemails.TRANSCRIPTION + " TEXT," +
                    Voicemails.TRANSCRIPTION_STATE + " INTEGER NOT NULL DEFAULT 0," +
                    Voicemails.STATE + " INTEGER," +
                    Voicemails.DIRTY + " INTEGER NOT NULL DEFAULT 0," +
                    Voicemails.DELETED + " INTEGER NOT NULL DEFAULT 0," +
                    Voicemails.BACKED_UP + " INTEGER NOT NULL DEFAULT 0," +
                    Voicemails.RESTORED + " INTEGER NOT NULL DEFAULT 0," +
                    Voicemails.ARCHIVED + " INTEGER NOT NULL DEFAULT 0," +
                    Voicemails.IS_OMTP_VOICEMAIL + " INTEGER NOT NULL DEFAULT 0" +
                    ");");

            String allTheColumns = Calls._ID + ", " +
                    Calls.NUMBER + ", " +
                    Calls.NUMBER_PRESENTATION + ", " +
                    Calls.POST_DIAL_DIGITS + ", " +
                    Calls.VIA_NUMBER + ", " +
                    Calls.DATE + ", " +
                    Calls.DURATION + ", " +
                    Calls.DATA_USAGE + ", " +
                    Calls.TYPE + ", " +
                    Calls.FEATURES + ", " +
                    Calls.PHONE_ACCOUNT_COMPONENT_NAME + ", " +
                    Calls.PHONE_ACCOUNT_ID + ", " +
                    Calls.PHONE_ACCOUNT_ADDRESS + ", " +
                    Calls.PHONE_ACCOUNT_HIDDEN + ", " +
                    Calls.SUB_ID + ", " +
                    Calls.NEW + ", " +
                    Calls.CACHED_NAME + ", " +
                    Calls.CACHED_NUMBER_TYPE + ", " +
                    Calls.CACHED_NUMBER_LABEL + ", " +
                    Calls.COUNTRY_ISO + ", " +
                    Calls.VOICEMAIL_URI + ", " +
                    Calls.IS_READ + ", " +
                    Calls.GEOCODED_LOCATION + ", " +
                    Calls.CACHED_LOOKUP_URI + ", " +
                    Calls.CACHED_MATCHED_NUMBER + ", " +
                    Calls.CACHED_NORMALIZED_NUMBER + ", " +
                    Calls.CACHED_PHOTO_ID + ", " +
                    Calls.CACHED_PHOTO_URI + ", " +
                    Calls.CACHED_FORMATTED_NUMBER + ", " +
                    Calls.ADD_FOR_ALL_USERS + ", " +
                    Calls.LAST_MODIFIED + ", " +
                    Calls.CALL_SCREENING_COMPONENT_NAME + ", " +
                    Calls.CALL_SCREENING_APP_NAME + ", " +
                    Calls.BLOCK_REASON + ", " +

                    Voicemails._DATA + ", " +
                    Voicemails.HAS_CONTENT + ", " +
                    Voicemails.MIME_TYPE + ", " +
                    Voicemails.SOURCE_DATA + ", " +
                    Voicemails.SOURCE_PACKAGE + ", " +
                    Voicemails.TRANSCRIPTION + ", " +
                    Voicemails.TRANSCRIPTION_STATE + ", " +
                    Voicemails.STATE + ", " +
                    Voicemails.DIRTY + ", " +
                    Voicemails.DELETED + ", " +
                    Voicemails.BACKED_UP + ", " +
                    Voicemails.RESTORED + ", " +
                    Voicemails.ARCHIVED + ", " +
                    Voicemails.IS_OMTP_VOICEMAIL;

            // .. so we insert into the new table all the values from the old table ...
            db.execSQL("INSERT INTO " + Tables.CALLS + " (" +
                    allTheColumns + ") SELECT " +
                    allTheColumns + " FROM " + oldTable);

            // .. and drop the old table we renamed.
            db.execSQL("DROP TABLE " + oldTable);

            db.setTransactionSuccessful();
        } finally {
            db.endTransaction();
        }
    }

    private void upgradeToVersion9(SQLiteDatabase db) {
        db.execSQL("ALTER TABLE calls ADD missed_reason INTEGER NOT NULL DEFAULT 0");
    }

    /**
     * Perform the migration from the contacts2.db (of the latest version) to the current calllog/
     * voicemail status tables.
     */
    private void migrateFromLegacyTables(SQLiteDatabase calllog) {
        final SQLiteDatabase contacts = getContactsWritableDatabaseForMigration();

        if (contacts == null) {
            Log.w(TAG, "Contacts DB == null, skipping migration. (running tests?)");
            return;
        }
        if (DEBUG) {
            Log.d(TAG, "migrateFromLegacyTables");
        }

        if ("1".equals(PropertyUtils.getProperty(calllog, DbProperties.DATA_MIGRATED, ""))) {
            return;
        }

        Log.i(TAG, "Migrating from old tables...");

        contacts.beginTransaction();
        try {
            if (!tableExists(contacts, LegacyConstants.CALLS_LEGACY)
                    || !tableExists(contacts, LegacyConstants.VOICEMAIL_STATUS_LEGACY)) {
                // This is fine on new devices. (or after a "clear data".)
                Log.i(TAG, "Source tables don't exist.");
                return;
            }
            calllog.beginTransaction();
            try {

                final ContentValues cv = new ContentValues();

                try (Cursor source = contacts.rawQuery(
                        "SELECT * FROM " + LegacyConstants.CALLS_LEGACY, null)) {
                    while (source.moveToNext()) {
                        cv.clear();

                        DatabaseUtils.cursorRowToContentValues(source, cv);

                        calllog.insertOrThrow(Tables.CALLS, null, cv);
                    }
                }

                try (Cursor source = contacts.rawQuery("SELECT * FROM " +
                        LegacyConstants.VOICEMAIL_STATUS_LEGACY, null)) {
                    while (source.moveToNext()) {
                        cv.clear();

                        DatabaseUtils.cursorRowToContentValues(source, cv);

                        calllog.insertOrThrow(Tables.VOICEMAIL_STATUS, null, cv);
                    }
                }

                contacts.execSQL("DROP TABLE " + LegacyConstants.CALLS_LEGACY + ";");
                contacts.execSQL("DROP TABLE " + LegacyConstants.VOICEMAIL_STATUS_LEGACY + ";");

                // Also copy the last sync time.
                PropertyUtils.setProperty(calllog, DbProperties.CALL_LOG_LAST_SYNCED,
                        PropertyUtils.getProperty(contacts,
                                LegacyConstants.CALL_LOG_LAST_SYNCED_LEGACY, null));

                Log.i(TAG, "Migration completed.");

                calllog.setTransactionSuccessful();
            } finally {
                calllog.endTransaction();
            }

            contacts.setTransactionSuccessful();
        } catch (RuntimeException e) {
            // We don't want to be stuck here, so we just swallow exceptions...
            Log.w(TAG, "Exception caught during migration", e);
        } finally {
            contacts.endTransaction();
        }
        PropertyUtils.setProperty(calllog, DbProperties.DATA_MIGRATED, "1");
    }

    @VisibleForTesting
    static boolean tableExists(SQLiteDatabase db, String table) {
        return DatabaseUtils.longForQuery(db,
                "select count(*) from sqlite_master where type='table' and name=?",
                new String[] {table}) > 0;
    }

    @VisibleForTesting
    @Nullable // We return null during tests when migration is not needed.
    SQLiteDatabase getContactsWritableDatabaseForMigration() {
        return ContactsDatabaseHelper.getInstance(mContext).getWritableDatabase();
    }

    public ArraySet<String> selectDistinctColumn(String table, String column) {
        final ArraySet<String> ret = new ArraySet<>();
        final SQLiteDatabase db = getReadableDatabase();
        final Cursor c = db.rawQuery("SELECT DISTINCT "
                + column
                + " FROM " + table, null);
        try {
            c.moveToPosition(-1);
            while (c.moveToNext()) {
                if (c.isNull(0)) {
                    continue;
                }
                final String s = c.getString(0);

                if (!TextUtils.isEmpty(s)) {
                    ret.add(s);
                }
            }
            return ret;
        } finally {
            c.close();
        }
    }

    @VisibleForTesting
    void closeForTest() {
        mOpenHelper.close();
    }

    public void wipeForTest() {
        getWritableDatabase().execSQL("DELETE FROM " + Tables.CALLS);
    }
}
