/*
 * 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 static android.Manifest.permission.ADD_VOICEMAIL;
import static android.Manifest.permission.READ_VOICEMAIL;

import android.content.ComponentName;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.ResolveInfo;
import android.database.Cursor;
import android.database.DatabaseUtils.InsertHelper;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;
import android.os.Binder;
import android.provider.CallLog.Calls;
import android.provider.VoicemailContract;
import android.provider.VoicemailContract.Status;
import android.provider.VoicemailContract.Voicemails;
import android.util.Log;
import com.android.common.io.MoreCloseables;
import com.android.providers.contacts.CallLogDatabaseHelper.Tables;
import com.android.providers.contacts.util.DbQueryUtils;
import com.google.android.collect.Lists;
import com.google.common.collect.Iterables;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * An implementation of {@link DatabaseModifier} for voicemail related tables which additionally
 * generates necessary notifications after the modification operation is performed.
 * The class generates notifications for both voicemail as well as call log URI depending on which
 * of then got affected by the change.
 */
public class DbModifierWithNotification implements DatabaseModifier {
    private static final String TAG = "DbModifierWithNotify";

    private static final String[] PROJECTION = new String[] {
            VoicemailContract.SOURCE_PACKAGE_FIELD
    };
    private static final int SOURCE_PACKAGE_COLUMN_INDEX = 0;
    private static final String NON_NULL_SOURCE_PACKAGE_SELECTION =
            VoicemailContract.SOURCE_PACKAGE_FIELD + " IS NOT NULL";

    private final String mTableName;
    private final SQLiteDatabase mDb;
    private final InsertHelper mInsertHelper;
    private final Context mContext;
    private final Uri mBaseUri;
    private final boolean mIsCallsTable;
    private final VoicemailPermissions mVoicemailPermissions;


    public DbModifierWithNotification(String tableName, SQLiteDatabase db, Context context) {
        this(tableName, db, null, context);
    }

    public DbModifierWithNotification(String tableName, InsertHelper insertHelper,
            Context context) {
        this(tableName, null, insertHelper, context);
    }

    private DbModifierWithNotification(String tableName, SQLiteDatabase db,
            InsertHelper insertHelper, Context context) {
        mTableName = tableName;
        mDb = db;
        mInsertHelper = insertHelper;
        mContext = context;
        mBaseUri = mTableName.equals(Tables.VOICEMAIL_STATUS) ?
                Status.CONTENT_URI : Voicemails.CONTENT_URI;
        mIsCallsTable = mTableName.equals(Tables.CALLS);
        mVoicemailPermissions = new VoicemailPermissions(mContext);
    }

    @Override
    public long insert(String table, String nullColumnHack, ContentValues values) {
        Set<String> packagesModified = getModifiedPackages(values);
        if (mIsCallsTable) {
            values.put(Calls.LAST_MODIFIED, System.currentTimeMillis());
        }
        long rowId = mDb.insert(table, nullColumnHack, values);
        if (rowId > 0 && packagesModified.size() != 0) {
            notifyVoicemailChangeOnInsert(ContentUris.withAppendedId(mBaseUri, rowId),
                    packagesModified);
        }
        if (rowId > 0 && mIsCallsTable) {
            notifyCallLogChange();
        }
        return rowId;
    }

    @Override
    public long insert(ContentValues values) {
        Set<String> packagesModified = getModifiedPackages(values);
        if (mIsCallsTable) {
            values.put(Calls.LAST_MODIFIED, System.currentTimeMillis());
        }
        long rowId = mInsertHelper.insert(values);
        if (rowId > 0 && packagesModified.size() != 0) {
            notifyVoicemailChangeOnInsert(
                    ContentUris.withAppendedId(mBaseUri, rowId), packagesModified);
        }
        if (rowId > 0 && mIsCallsTable) {
            notifyCallLogChange();
        }
        return rowId;
    }

    private void notifyCallLogChange() {
        mContext.getContentResolver().notifyChange(Calls.CONTENT_URI, null, false);

        Intent intent = new Intent("android.intent.action.CALL_LOG_CHANGE");
        intent.setComponent(new ComponentName("com.android.calllogbackup",
                "com.android.calllogbackup.CallLogChangeReceiver"));

        if (!mContext.getPackageManager().queryBroadcastReceivers(intent, 0).isEmpty()) {
            mContext.sendBroadcast(intent);
        }
    }

    private void notifyVoicemailChangeOnInsert(Uri notificationUri, Set<String> packagesModified) {
        if (mIsCallsTable) {
            notifyVoicemailChange(notificationUri, packagesModified,
                    VoicemailContract.ACTION_NEW_VOICEMAIL, Intent.ACTION_PROVIDER_CHANGED);
        } else {
            notifyVoicemailChange(notificationUri, packagesModified,
                    Intent.ACTION_PROVIDER_CHANGED);
        }
    }

    @Override
    public int update(Uri uri, String table, ContentValues values, String whereClause,
            String[] whereArgs) {
        Set<String> packagesModified = getModifiedPackages(whereClause, whereArgs);
        packagesModified.addAll(getModifiedPackages(values));

        boolean isVoicemail = packagesModified.size() != 0;

        boolean hasMarkedRead = false;
        if (mIsCallsTable) {
            values.put(Calls.LAST_MODIFIED, System.currentTimeMillis());

            if (isVoicemail) {
                // If a calling package is modifying its own entries, it means that the change came
                // from the server and thus is synced or "clean". Otherwise, it means that a local
                // change is being made to the database, so the entries should be marked as "dirty"
                // so that the corresponding sync adapter knows they need to be synced.
                final int isDirty = isSelfModifyingOrInternal(packagesModified) ? 0 : 1;
                values.put(VoicemailContract.Voicemails.DIRTY, isDirty);

                if (isDirty == 0 && values.containsKey(Calls.IS_READ) && getAsBoolean(values,
                        Calls.IS_READ)) {
                    // If the server has set the IS_READ, it should also unset the new flag
                    if (!values.containsKey(Calls.NEW)) {
                        values.put(Calls.NEW, 0);
                        hasMarkedRead = true;
                    }
                }
            }
        }

        int count = mDb.update(table, values, whereClause, whereArgs);
        if (count > 0 && isVoicemail) {
            notifyVoicemailChange(mBaseUri, packagesModified, Intent.ACTION_PROVIDER_CHANGED);
        }
        if (count > 0 && mIsCallsTable) {
            notifyCallLogChange();
        }
        if (hasMarkedRead) {
            // A "New" voicemail has been marked as read by the server. This voicemail is no longer
            // new but the content consumer might still think it is. ACTION_NEW_VOICEMAIL should
            // trigger a rescan of new voicemails.
            mContext.sendBroadcast(
                    new Intent(VoicemailContract.ACTION_NEW_VOICEMAIL, uri),
                    READ_VOICEMAIL);
        }
        return count;
    }

    @Override
    public int delete(String table, String whereClause, String[] whereArgs) {
        Set<String> packagesModified = getModifiedPackages(whereClause, whereArgs);
        boolean isVoicemail = packagesModified.size() != 0;

        // If a deletion is made by a package that is not the package that inserted the voicemail,
        // this means that the user deleted the voicemail. However, we do not want to delete it from
        // the database until after the server has been notified of the deletion. To ensure this,
        // mark the entry as "deleted"--deleted entries should be hidden from the user.
        // Once the changes are synced to the server, delete will be called again, this time
        // removing the rows from the table.
        // If the deletion is being made by the package that inserted the voicemail or by
        // CP2 (cleanup after uninstall), then we don't need to wait for sync, so just delete it.
        final int count;
        if (mIsCallsTable && isVoicemail && !isSelfModifyingOrInternal(packagesModified)) {
            ContentValues values = new ContentValues();
            values.put(VoicemailContract.Voicemails.DIRTY, 1);
            values.put(VoicemailContract.Voicemails.DELETED, 1);
            values.put(VoicemailContract.Voicemails.LAST_MODIFIED, System.currentTimeMillis());
            count = mDb.update(table, values, whereClause, whereArgs);
        } else {
            count = mDb.delete(table, whereClause, whereArgs);
        }

        if (count > 0 && isVoicemail) {
            notifyVoicemailChange(mBaseUri, packagesModified, Intent.ACTION_PROVIDER_CHANGED);
        }
        if (count > 0 && mIsCallsTable) {
            notifyCallLogChange();
        }
        return count;
    }

    /**
     * Returns the set of packages affected when a modify operation is run for the specified
     * where clause. When called from an insert operation an empty set returned by this method
     * implies (indirectly) that this does not affect any voicemail entry, as a voicemail entry is
     * always expected to have the source package field set.
     */
    private Set<String> getModifiedPackages(String whereClause, String[] whereArgs) {
        Set<String> modifiedPackages = new HashSet<String>();
        Cursor cursor = mDb.query(mTableName, PROJECTION,
                DbQueryUtils.concatenateClauses(NON_NULL_SOURCE_PACKAGE_SELECTION, whereClause),
                whereArgs, null, null, null);
        while(cursor.moveToNext()) {
            modifiedPackages.add(cursor.getString(SOURCE_PACKAGE_COLUMN_INDEX));
        }
        MoreCloseables.closeQuietly(cursor);
        return modifiedPackages;
    }

    /**
     * Returns the source package that gets affected (in an insert/update operation) by the supplied
     * content values. An empty set returned by this method also implies (indirectly) that this does
     * not affect any voicemail entry, as a voicemail entry is always expected to have the source
     * package field set.
     */
    private Set<String> getModifiedPackages(ContentValues values) {
        Set<String> impactedPackages = new HashSet<String>();
        if(values.containsKey(VoicemailContract.SOURCE_PACKAGE_FIELD)) {
            impactedPackages.add(values.getAsString(VoicemailContract.SOURCE_PACKAGE_FIELD));
        }
        return impactedPackages;
    }

    /**
     * @param packagesModified source packages that inserted the voicemail that is being modified
     * @return {@code true} if the caller is modifying its own voicemail, or this is an internal
     *         transaction, {@code false} otherwise.
     */
    private boolean isSelfModifyingOrInternal(Set<String> packagesModified) {
        final Collection<String> callingPackages = getCallingPackages();
        if (callingPackages == null) {
            return false;
        }
        // The last clause has the same effect as doing Process.myUid() == Binder.getCallingUid(),
        // but allows us to mock the results for testing.
        return packagesModified.size() == 1 && (callingPackages.contains(
                Iterables.getOnlyElement(packagesModified))
                        || callingPackages.contains(mContext.getPackageName()));
    }

    private void notifyVoicemailChange(Uri notificationUri, Set<String> modifiedPackages,
            String... intentActions) {
        // Notify the observers.
        // Must be done only once, even if there are multiple broadcast intents.
        mContext.getContentResolver().notifyChange(notificationUri, null, true);
        Collection<String> callingPackages = getCallingPackages();
        // Now fire individual intents.
        for (String intentAction : intentActions) {
            // self_change extra should be included only for provider_changed events.
            boolean includeSelfChangeExtra = intentAction.equals(Intent.ACTION_PROVIDER_CHANGED);
            for (ComponentName component :
                    getBroadcastReceiverComponents(intentAction, notificationUri)) {
                // Ignore any package that is not affected by the change and don't have full access
                // either.
                if (!modifiedPackages.contains(component.getPackageName()) &&
                        !mVoicemailPermissions.packageHasReadAccess(
                                component.getPackageName())) {
                    continue;
                }

                Intent intent = new Intent(intentAction, notificationUri);
                intent.setComponent(component);
                if (includeSelfChangeExtra && callingPackages != null) {
                    intent.putExtra(VoicemailContract.EXTRA_SELF_CHANGE,
                            callingPackages.contains(component.getPackageName()));
                }
                String permissionNeeded = modifiedPackages.contains(component.getPackageName()) ?
                        ADD_VOICEMAIL : READ_VOICEMAIL;
                mContext.sendBroadcast(intent, permissionNeeded);
                Log.v(TAG, String.format("Sent intent. act:%s, url:%s, comp:%s, perm:%s," +
                        " self_change:%s", intent.getAction(), intent.getData(),
                        component.getClassName(), permissionNeeded,
                        intent.hasExtra(VoicemailContract.EXTRA_SELF_CHANGE) ?
                                intent.getBooleanExtra(VoicemailContract.EXTRA_SELF_CHANGE, false) :
                                        null));
            }
        }
    }

    /** Determines the components that can possibly receive the specified intent. */
    private List<ComponentName> getBroadcastReceiverComponents(String intentAction, Uri uri) {
        Intent intent = new Intent(intentAction, uri);
        List<ComponentName> receiverComponents = new ArrayList<ComponentName>();
        // For broadcast receivers ResolveInfo.activityInfo is the one that is populated.
        for (ResolveInfo resolveInfo :
                mContext.getPackageManager().queryBroadcastReceivers(intent, 0)) {
            ActivityInfo activityInfo = resolveInfo.activityInfo;
            receiverComponents.add(new ComponentName(activityInfo.packageName, activityInfo.name));
        }
        return receiverComponents;
    }

    /**
     * Returns the package names of the calling process. If the calling process has more than
     * one packages, this returns them all
     */
    private Collection<String> getCallingPackages() {
        int caller = Binder.getCallingUid();
        if (caller == 0) {
            return null;
        }
        return Lists.newArrayList(mContext.getPackageManager().getPackagesForUid(caller));
    }

    /**
     * A variant of {@link ContentValues#getAsBoolean(String)} that also treat the string "0" as
     * false and other integer string as true. 0, 1, false, true, "0", "1", "false", "true" might
     * all be inserted into the ContentValues as a boolean, but "0" and "1" are not handled by
     * {@link ContentValues#getAsBoolean(String)}
     */
    private static Boolean getAsBoolean(ContentValues values, String key) {
        Object value = values.get(key);
        if (value instanceof CharSequence) {
            try {
                int intValue = Integer.parseInt(value.toString());
                return intValue != 0;
            } catch (NumberFormatException nfe) {
                // Do nothing.
            }
        }
        return values.getAsBoolean(key);
    }
}
