/*
 * Copyright (C) 2010 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.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.provider.ContactsContract;
import android.provider.ContactsContract.CommonDataKinds.Email;
import android.provider.ContactsContract.CommonDataKinds.Nickname;
import android.provider.ContactsContract.CommonDataKinds.Organization;
import android.provider.ContactsContract.CommonDataKinds.Phone;
import android.provider.ContactsContract.CommonDataKinds.StructuredName;
import android.provider.ContactsContract.Data;
import android.text.TextUtils;
import com.android.providers.contacts.ContactsDatabaseHelper.DataColumns;
import com.android.providers.contacts.ContactsDatabaseHelper.MimetypesColumns;
import com.android.providers.contacts.ContactsDatabaseHelper.PresenceColumns;
import com.android.providers.contacts.ContactsDatabaseHelper.Tables;
import com.android.providers.contacts.aggregation.AbstractContactAggregator;

/**
 * Handles inserts and update for a specific Data type.
 */
public abstract class DataRowHandler {

    private static final String[] HASH_INPUT_COLUMNS = new String[] {
            Data.DATA1, Data.DATA2};

    public interface DataDeleteQuery {
        public static final String TABLE = Tables.DATA_JOIN_MIMETYPES;

        public static final String[] CONCRETE_COLUMNS = new String[] {
            DataColumns.CONCRETE_ID,
            MimetypesColumns.MIMETYPE,
            Data.RAW_CONTACT_ID,
            Data.IS_PRIMARY,
            Data.DATA1,
        };

        public static final String[] COLUMNS = new String[] {
            Data._ID,
            MimetypesColumns.MIMETYPE,
            Data.RAW_CONTACT_ID,
            Data.IS_PRIMARY,
            Data.DATA1,
        };

        public static final int _ID = 0;
        public static final int MIMETYPE = 1;
        public static final int RAW_CONTACT_ID = 2;
        public static final int IS_PRIMARY = 3;
        public static final int DATA1 = 4;
    }

    public interface DataUpdateQuery {
        String[] COLUMNS = { Data._ID, Data.RAW_CONTACT_ID, Data.MIMETYPE };

        int _ID = 0;
        int RAW_CONTACT_ID = 1;
        int MIMETYPE = 2;
    }

    protected final Context mContext;
    protected final ContactsDatabaseHelper mDbHelper;
    protected final AbstractContactAggregator mContactAggregator;
    protected String[] mSelectionArgs1 = new String[1];
    protected final String mMimetype;
    protected long mMimetypeId;

    @SuppressWarnings("all")
    public DataRowHandler(Context context, ContactsDatabaseHelper dbHelper,
            AbstractContactAggregator aggregator, String mimetype) {
        mContext = context;
        mDbHelper = dbHelper;
        mContactAggregator = aggregator;
        mMimetype = mimetype;

        // To ensure the data column position. This is dead code if properly configured.
        if (StructuredName.DISPLAY_NAME != Data.DATA1 || Nickname.NAME != Data.DATA1
                || Organization.COMPANY != Data.DATA1 || Phone.NUMBER != Data.DATA1
                || Email.DATA != Data.DATA1) {
            throw new AssertionError("Some of ContactsContract.CommonDataKinds class primary"
                    + " data is not in DATA1 column");
        }
    }

    protected long getMimeTypeId() {
        if (mMimetypeId == 0) {
            mMimetypeId = mDbHelper.getMimeTypeId(mMimetype);
        }
        return mMimetypeId;
    }

    /**
     * Inserts a row into the {@link Data} table.
     */
    public long insert(SQLiteDatabase db, TransactionContext txContext, long rawContactId,
            ContentValues values) {
        // Generate hash_id from data1 and data2 columns.
        // For photo, use data15 column instead of data1 and data2 to generate hash_id.
        handleHashIdForInsert(values);
        final long dataId = db.insert(Tables.DATA, null, values);

        final Integer primary = values.getAsInteger(Data.IS_PRIMARY);
        final Integer superPrimary = values.getAsInteger(Data.IS_SUPER_PRIMARY);
        if ((primary != null && primary != 0) || (superPrimary != null && superPrimary != 0)) {
            final long mimeTypeId = getMimeTypeId();
            mDbHelper.setIsPrimary(rawContactId, dataId, mimeTypeId);
            txContext.markRawContactMetadataDirty(rawContactId, /* isMetadataSyncAdapter =*/false);

            // We also have to make sure that no other data item on this raw_contact is
            // configured super primary
            if (superPrimary != null) {
                if (superPrimary != 0) {
                    mDbHelper.setIsSuperPrimary(rawContactId, dataId, mimeTypeId);
                } else {
                    mDbHelper.clearSuperPrimary(rawContactId, mimeTypeId);
                }
            } else {
                // if there is already another data item configured as super-primary,
                // take over the flag (which will automatically remove it from the other item)
                if (mDbHelper.rawContactHasSuperPrimary(rawContactId, mimeTypeId)) {
                    mDbHelper.setIsSuperPrimary(rawContactId, dataId, mimeTypeId);
                }
            }
        }

        if (containsSearchableColumns(values)) {
            txContext.invalidateSearchIndexForRawContact(rawContactId);
        }

        return dataId;
    }

    /**
     * Validates data and updates a {@link Data} row using the cursor, which contains
     * the current data.
     *
     * @return true if update changed something
     */
    public boolean update(SQLiteDatabase db, TransactionContext txContext,
            ContentValues values, Cursor c, boolean callerIsSyncAdapter,
            boolean callerIsMetadataSyncAdapter) {
        long dataId = c.getLong(DataUpdateQuery._ID);
        long rawContactId = c.getLong(DataUpdateQuery.RAW_CONTACT_ID);

        handlePrimaryAndSuperPrimary(txContext, values, dataId, rawContactId,
                callerIsMetadataSyncAdapter);
        handleHashIdForUpdate(values, dataId);

        if (values.size() > 0) {
            mSelectionArgs1[0] = String.valueOf(dataId);
            db.update(Tables.DATA, values, Data._ID + " =?", mSelectionArgs1);
        }

        if (containsSearchableColumns(values)) {
            txContext.invalidateSearchIndexForRawContact(rawContactId);
        }

        txContext.markRawContactDirtyAndChanged(rawContactId, callerIsSyncAdapter);

        return true;
    }

    public boolean hasSearchableData() {
        return false;
    }

    public boolean containsSearchableColumns(ContentValues values) {
        return false;
    }

    public void appendSearchableData(SearchIndexManager.IndexBuilder builder) {
    }

    /**
     * Fetch data1, data2, and data15 from values if they exist, and generate hash_id
     * if one of data1 and data2 columns is set, otherwise using data15 instead.
     * hash_id is null if all of these three field is null.
     * Add hash_id key to values.
     */
    public void handleHashIdForInsert(ContentValues values) {
        final String data1 = values.getAsString(Data.DATA1);
        final String data2 = values.getAsString(Data.DATA2);
        final String photoHashId= mDbHelper.getPhotoHashId();

        String hashId;
        if (ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE.equals(mMimetype)) {
            hashId = photoHashId;
        } else if (!TextUtils.isEmpty(data1) || !TextUtils.isEmpty(data2)) {
            hashId = mDbHelper.generateHashId(data1, data2);
        } else {
            hashId = null;
        }
        if (TextUtils.isEmpty(hashId)) {
            values.putNull(Data.HASH_ID);
        } else {
            values.put(Data.HASH_ID, hashId);
        }
    }

    /**
     * Compute hash_id column and add it to values.
     * If this is not a photo field, and one of data1 and data2 changed, re-compute hash_id with new
     * data1 and data2.
     * If this is a photo field, no need to change hash_id.
     */
    private void handleHashIdForUpdate(ContentValues values, long dataId) {
        if (!ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE.equals(mMimetype)
                && (values.containsKey(Data.DATA1) || values.containsKey(Data.DATA2))) {
            String data1 = values.getAsString(Data.DATA1);
            String data2 = values.getAsString(Data.DATA2);
            mSelectionArgs1[0] = String.valueOf(dataId);
            final Cursor c = mDbHelper.getReadableDatabase().query(Tables.DATA,
                    HASH_INPUT_COLUMNS, Data._ID + "=?", mSelectionArgs1, null, null, null);
            try {
                if (c.moveToFirst()) {
                    data1 = values.containsKey(Data.DATA1) ? data1 : c.getString(0);
                    data2 = values.containsKey(Data.DATA2) ? data2 : c.getString(1);
                }
            } finally {
                c.close();
            }

            String hashId = mDbHelper.generateHashId(data1, data2);
            if (TextUtils.isEmpty(hashId)) {
                values.putNull(Data.HASH_ID);
            } else {
                values.put(Data.HASH_ID, hashId);
            }
        }
    }

    /**
     * Ensures that all super-primary and primary flags of this raw_contact are
     * configured correctly
     */
    private void handlePrimaryAndSuperPrimary(TransactionContext txContext, ContentValues values,
            long dataId, long rawContactId, boolean callerIsMetadataSyncAdapter) {
        final boolean hasPrimary = values.getAsInteger(Data.IS_PRIMARY) != null;
        final boolean hasSuperPrimary = values.getAsInteger(Data.IS_SUPER_PRIMARY) != null;

        // Nothing to do? Bail out early
        if (!hasPrimary && !hasSuperPrimary) return;

        txContext.markRawContactMetadataDirty(rawContactId, callerIsMetadataSyncAdapter);

        final long mimeTypeId = getMimeTypeId();

        // Check if we want to clear values
        final boolean clearPrimary = hasPrimary &&
                values.getAsInteger(Data.IS_PRIMARY) == 0;
        final boolean clearSuperPrimary = hasSuperPrimary &&
                values.getAsInteger(Data.IS_SUPER_PRIMARY) == 0;

        if (clearPrimary || clearSuperPrimary) {
            // Test whether these values are currently set
            mSelectionArgs1[0] = String.valueOf(dataId);
            final String[] cols = new String[] { Data.IS_PRIMARY, Data.IS_SUPER_PRIMARY };
            final Cursor c = mDbHelper.getReadableDatabase().query(Tables.DATA,
                    cols, Data._ID + "=?", mSelectionArgs1, null, null, null);
            try {
                if (c.moveToFirst()) {
                    final boolean isPrimary = c.getInt(0) != 0;
                    final boolean isSuperPrimary = c.getInt(1) != 0;
                    // Clear values if they are currently set
                    if (isSuperPrimary) {
                        mDbHelper.clearSuperPrimary(rawContactId, mimeTypeId);
                    }
                    if (clearPrimary && isPrimary) {
                        mDbHelper.setIsPrimary(rawContactId, -1, mimeTypeId);
                    }
                }
            } finally {
                c.close();
            }
        } else {
            // Check if we want to set values
            final boolean setPrimary = hasPrimary &&
                    values.getAsInteger(Data.IS_PRIMARY) != 0;
            final boolean setSuperPrimary = hasSuperPrimary &&
                    values.getAsInteger(Data.IS_SUPER_PRIMARY) != 0;
            if (setSuperPrimary) {
                // Set both super primary and primary
                mDbHelper.setIsSuperPrimary(rawContactId, dataId, mimeTypeId);
                mDbHelper.setIsPrimary(rawContactId, dataId, mimeTypeId);
            } else if (setPrimary) {
                // Primary was explicitly set, but super-primary was not.
                // In this case we set super-primary on this data item, if
                // any data item of the same raw-contact already is super-primary
                if (mDbHelper.rawContactHasSuperPrimary(rawContactId, mimeTypeId)) {
                    mDbHelper.setIsSuperPrimary(rawContactId, dataId, mimeTypeId);
                }
                mDbHelper.setIsPrimary(rawContactId, dataId, mimeTypeId);
            }
        }

        // Now that we've taken care of clearing this, remove it from "values".
        values.remove(Data.IS_SUPER_PRIMARY);
        values.remove(Data.IS_PRIMARY);
    }

    public int delete(SQLiteDatabase db, TransactionContext txContext, Cursor c) {
        long dataId = c.getLong(DataDeleteQuery._ID);
        long rawContactId = c.getLong(DataDeleteQuery.RAW_CONTACT_ID);
        boolean primary = c.getInt(DataDeleteQuery.IS_PRIMARY) != 0;
        mSelectionArgs1[0] = String.valueOf(dataId);
        int count = db.delete(Tables.DATA, Data._ID + "=?", mSelectionArgs1);
        mSelectionArgs1[0] = String.valueOf(rawContactId);
        db.delete(Tables.PRESENCE, PresenceColumns.RAW_CONTACT_ID + "=?", mSelectionArgs1);
        if (count != 0 && primary) {
            fixPrimary(db, rawContactId);
            txContext.markRawContactMetadataDirty(rawContactId, /* isMetadataSyncAdapter =*/false);
        }

        if (hasSearchableData()) {
            txContext.invalidateSearchIndexForRawContact(rawContactId);
        }

        return count;
    }

    private void fixPrimary(SQLiteDatabase db, long rawContactId) {
        long mimeTypeId = getMimeTypeId();
        long primaryId = -1;
        int primaryType = -1;
        mSelectionArgs1[0] = String.valueOf(rawContactId);
        Cursor c = db.query(DataDeleteQuery.TABLE,
                DataDeleteQuery.CONCRETE_COLUMNS,
                Data.RAW_CONTACT_ID + "=?" +
                    " AND " + DataColumns.MIMETYPE_ID + "=" + mimeTypeId,
                mSelectionArgs1, null, null, null);
        try {
            while (c.moveToNext()) {
                long dataId = c.getLong(DataDeleteQuery._ID);
                int type = c.getInt(DataDeleteQuery.DATA1);
                if (primaryType == -1 || getTypeRank(type) < getTypeRank(primaryType)) {
                    primaryId = dataId;
                    primaryType = type;
                }
            }
        } finally {
            c.close();
        }
        if (primaryId != -1) {
            mDbHelper.setIsPrimary(rawContactId, primaryId, mimeTypeId);
        }
    }

    /**
     * Returns the rank of a specific record type to be used in determining the primary
     * row. Lower number represents higher priority.
     */
    protected int getTypeRank(int type) {
        return 0;
    }

    protected void fixRawContactDisplayName(SQLiteDatabase db, TransactionContext txContext,
            long rawContactId) {
        if (!isNewRawContact(txContext, rawContactId)) {
            mDbHelper.updateRawContactDisplayName(db, rawContactId);
            mContactAggregator.updateDisplayNameForRawContact(db, rawContactId);
        }
    }

    private boolean isNewRawContact(TransactionContext txContext, long rawContactId) {
        return txContext.isNewRawContact(rawContactId);
    }

    /**
     * Return set of values, using current values at given {@link Data#_ID}
     * as baseline, but augmented with any updates.  Returns null if there is
     * no change.
     */
    public ContentValues getAugmentedValues(SQLiteDatabase db, long dataId,
            ContentValues update) {
        boolean changing = false;
        final ContentValues values = new ContentValues();
        mSelectionArgs1[0] = String.valueOf(dataId);
        final Cursor cursor = db.query(Tables.DATA, null, Data._ID + "=?",
                mSelectionArgs1, null, null, null);
        try {
            if (cursor.moveToFirst()) {
                for (int i = 0; i < cursor.getColumnCount(); i++) {
                    final String key = cursor.getColumnName(i);
                    final String value = cursor.getString(i);
                    if (!changing && update.containsKey(key)) {
                        Object newValue = update.get(key);
                        String newString = newValue == null ? null : newValue.toString();
                        changing |= !TextUtils.equals(newString, value);
                    }
                    values.put(key, value);
                }
            }
        } finally {
            cursor.close();
        }
        if (!changing) {
            return null;
        }

        values.putAll(update);
        return values;
    }

    public void triggerAggregation(TransactionContext txContext, long rawContactId) {
        mContactAggregator.triggerAggregation(txContext, rawContactId);
    }

    /**
     * Test all against {@link TextUtils#isEmpty(CharSequence)}.
     */
    public boolean areAllEmpty(ContentValues values, String[] keys) {
        for (String key : keys) {
            if (!TextUtils.isEmpty(values.getAsString(key))) {
                return false;
            }
        }
        return true;
    }

    /**
     * Returns true if a value (possibly null) is specified for at least one of the supplied keys.
     */
    public boolean areAnySpecified(ContentValues values, String[] keys) {
        for (String key : keys) {
            if (values.containsKey(key)) {
                return true;
            }
        }
        return false;
    }
}
