/*
 * 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.provider.VoicemailContract.SOURCE_PACKAGE_FIELD;

import static com.android.providers.contacts.util.DbQueryUtils.concatenateClauses;
import static com.android.providers.contacts.util.DbQueryUtils.getEqualityClause;

import android.app.AppOpsManager;
import android.content.ContentProvider;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Binder;
import android.os.ParcelFileDescriptor;
import android.provider.BaseColumns;
import android.provider.VoicemailContract;
import android.provider.VoicemailContract.Status;
import android.provider.VoicemailContract.Voicemails;
import android.util.ArraySet;
import android.util.Log;

import com.android.providers.contacts.CallLogDatabaseHelper.Tables;
import com.android.providers.contacts.util.ContactsPermissions;
import com.android.providers.contacts.util.PackageUtils;
import com.android.providers.contacts.util.SelectionBuilder;
import com.android.providers.contacts.util.TypedUriMatcherImpl;
import com.android.providers.contacts.util.UserUtils;

import com.google.common.annotations.VisibleForTesting;

import java.io.FileNotFoundException;
import java.util.Arrays;
import java.util.List;
import java.util.Set;

/**
 * An implementation of the Voicemail content provider. This class in the entry point for both
 * voicemail content ('calls') table and 'voicemail_status' table. This class performs all common
 * permission checks and then delegates database level operations to respective table delegate
 * objects.
 */
public class VoicemailContentProvider extends ContentProvider
        implements VoicemailTable.DelegateHelper {
    private static final String TAG = "VoicemailProvider";

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

    private static final int BACKGROUND_TASK_SCAN_STALE_PACKAGES = 0;

    private ContactsTaskScheduler mTaskScheduler;

    private VoicemailPermissions mVoicemailPermissions;
    private VoicemailTable.Delegate mVoicemailContentTable;
    private VoicemailTable.Delegate mVoicemailStatusTable;

    @Override
    public boolean onCreate() {
        if (VERBOSE_LOGGING) {
            Log.v(TAG, "onCreate: " + this.getClass().getSimpleName()
                    + " user=" + android.os.Process.myUserHandle().getIdentifier());
        }
        if (Log.isLoggable(Constants.PERFORMANCE_TAG, Log.INFO)) {
            Log.i(Constants.PERFORMANCE_TAG, "VoicemailContentProvider.onCreate start");
        }
        Context context = context();

        // ADD_VOICEMAIL permission guards read and write. We do the same with app ops.
        // The permission name doesn't reflect its function but we cannot rename it.
        setAppOps(AppOpsManager.OP_ADD_VOICEMAIL, AppOpsManager.OP_ADD_VOICEMAIL);

        mVoicemailPermissions = new VoicemailPermissions(context);
        mVoicemailContentTable = new VoicemailContentTable(Tables.CALLS, context,
                getDatabaseHelper(context), this, createCallLogInsertionHelper(context));
        mVoicemailStatusTable = new VoicemailStatusTable(Tables.VOICEMAIL_STATUS, context,
                getDatabaseHelper(context), this);

        mTaskScheduler = new ContactsTaskScheduler(getClass().getSimpleName()) {
            @Override
            public void onPerformTask(int taskId, Object arg) {
                performBackgroundTask(taskId, arg);
            }
        };

        scheduleScanStalePackages();

        ContactsPackageMonitor.start(getContext());

        if (Log.isLoggable(Constants.PERFORMANCE_TAG, Log.INFO)) {
            Log.i(Constants.PERFORMANCE_TAG, "VoicemailContentProvider.onCreate finish");
        }
        return true;
    }

    @VisibleForTesting
    void scheduleScanStalePackages() {
        scheduleTask(BACKGROUND_TASK_SCAN_STALE_PACKAGES, null);
    }

    @VisibleForTesting
    void scheduleTask(int taskId, Object arg) {
        mTaskScheduler.scheduleTask(taskId, arg);
    }

    @VisibleForTesting
    /*package*/ CallLogInsertionHelper createCallLogInsertionHelper(Context context) {
        return DefaultCallLogInsertionHelper.getInstance(context);
    }

    @VisibleForTesting
    /*package*/ CallLogDatabaseHelper getDatabaseHelper(Context context) {
        return CallLogDatabaseHelper.getInstance(context);
    }

    @VisibleForTesting
    /*package*/ Context context() {
        return getContext();
    }

    @Override
    public String getType(Uri uri) {
        UriData uriData = null;
        try {
            uriData = UriData.createUriData(uri);
        } catch (IllegalArgumentException ignored) {
            // Special case: for illegal URIs, we return null rather than thrown an exception.
            return null;
        }
        return getTableDelegate(uriData).getType(uriData);
    }

    @Override
    public Uri insert(Uri uri, ContentValues values) {
        if (VERBOSE_LOGGING) {
            Log.v(TAG, "insert: uri=" + uri + "  values=[" + values + "]" +
                    " CPID=" + Binder.getCallingPid());
        }
        UriData uriData = checkPermissionsAndCreateUriDataForWrite(uri, values);
        return getTableDelegate(uriData).insert(uriData, values);
    }

    @Override
    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
            String sortOrder) {
        if (VERBOSE_LOGGING) {
            Log.v(TAG, "query: uri=" + uri + "  projection=" + Arrays.toString(projection) +
                    "  selection=[" + selection + "]  args=" + Arrays.toString(selectionArgs) +
                    "  order=[" + sortOrder + "] CPID=" + Binder.getCallingPid() +
                    " User=" + UserUtils.getCurrentUserHandle(getContext()));
        }
        UriData uriData = checkPermissionsAndCreateUriDataForRead(uri);
        SelectionBuilder selectionBuilder = new SelectionBuilder(selection);
        selectionBuilder.addClause(getPackageRestrictionClause(true/*isQuery*/));
        return getTableDelegate(uriData).query(uriData, projection, selectionBuilder.build(),
                selectionArgs, sortOrder);
    }

    @Override
    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
        if (VERBOSE_LOGGING) {
            Log.v(TAG, "update: uri=" + uri +
                    "  selection=[" + selection + "]  args=" + Arrays.toString(selectionArgs) +
                    "  values=[" + values + "] CPID=" + Binder.getCallingPid() +
                    " User=" + UserUtils.getCurrentUserHandle(getContext()));
        }
        UriData uriData = checkPermissionsAndCreateUriDataForWrite(uri, values);
        SelectionBuilder selectionBuilder = new SelectionBuilder(selection);
        selectionBuilder.addClause(getPackageRestrictionClause(false/*isQuery*/));
        return getTableDelegate(uriData).update(uriData, values, selectionBuilder.build(),
                selectionArgs);
    }

    @Override
    public int delete(Uri uri, String selection, String[] selectionArgs) {
        if (VERBOSE_LOGGING) {
            Log.v(TAG, "delete: uri=" + uri +
                    "  selection=[" + selection + "]  args=" + Arrays.toString(selectionArgs) +
                    " CPID=" + Binder.getCallingPid() +
                    " User=" + UserUtils.getCurrentUserHandle(getContext()));
        }
        UriData uriData = checkPermissionsAndCreateUriDataForWrite(uri);
        SelectionBuilder selectionBuilder = new SelectionBuilder(selection);
        selectionBuilder.addClause(getPackageRestrictionClause(false/*isQuery*/));
        return getTableDelegate(uriData).delete(uriData, selectionBuilder.build(), selectionArgs);
    }

    @Override
    public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {
        boolean success = false;
        try {
            UriData uriData = null;
            if (mode.equals("r")) {
                uriData = checkPermissionsAndCreateUriDataForRead(uri);
            } else {
                uriData = checkPermissionsAndCreateUriDataForWrite(uri);
            }
            // openFileHelper() relies on "_data" column to be populated with the file path.
            final ParcelFileDescriptor ret = getTableDelegate(uriData).openFile(uriData, mode);
            success = true;
            return ret;
        } finally {
            if (VERBOSE_LOGGING) {
                Log.v(TAG, "openFile uri=" + uri + " mode=" + mode + " success=" + success +
                        " CPID=" + Binder.getCallingPid() +
                        " User=" + UserUtils.getCurrentUserHandle(getContext()));
            }
        }
    }

    /** Returns the correct table delegate object that can handle this URI. */
    private VoicemailTable.Delegate getTableDelegate(UriData uriData) {
        switch (uriData.getUriType()) {
            case STATUS:
            case STATUS_ID:
                return mVoicemailStatusTable;
            case VOICEMAILS:
            case VOICEMAILS_ID:
                return mVoicemailContentTable;
            case NO_MATCH:
                throw new IllegalStateException("Invalid uri type for uri: " + uriData.getUri());
            default:
                throw new IllegalStateException("Impossible, all cases are covered.");
        }
    }

    /**
     * Decorates a URI by providing methods to get various properties from the URI.
     */
    public static class UriData {
        private final Uri mUri;
        private final String mId;
        private final String mSourcePackage;
        private final VoicemailUriType mUriType;

        private UriData(Uri uri, VoicemailUriType uriType, String id, String sourcePackage) {
            mUriType = uriType;
            mUri = uri;
            mId = id;
            mSourcePackage = sourcePackage;
        }

        /** Gets the original URI to which this {@link UriData} corresponds. */
        public final Uri getUri() {
            return mUri;
        }

        /** Tells us if our URI has an individual voicemail id. */
        public final boolean hasId() {
            return mId != null;
        }

        /** Gets the ID for the voicemail. */
        public final String getId() {
            return mId;
        }

        /** Tells us if our URI has a source package string. */
        public final boolean hasSourcePackage() {
            return mSourcePackage != null;
        }

        /** Gets the source package. */
        public final String getSourcePackage() {
            return mSourcePackage;
        }

        /** Gets the Voicemail URI type. */
        public final VoicemailUriType getUriType() {
            return mUriType;
        }

        /** Builds a where clause from the URI data. */
        public final String getWhereClause() {
            return concatenateClauses(
                    (hasId() ? getEqualityClause(BaseColumns._ID, getId()) : null),
                    (hasSourcePackage() ? getEqualityClause(SOURCE_PACKAGE_FIELD,
                            getSourcePackage()) : null));
        }

        /** Create a {@link UriData} corresponding to a given uri. */
        public static UriData createUriData(Uri uri) {
            String sourcePackage = uri.getQueryParameter(
                    VoicemailContract.PARAM_KEY_SOURCE_PACKAGE);
            List<String> segments = uri.getPathSegments();
            VoicemailUriType uriType = createUriMatcher().match(uri);
            switch (uriType) {
                case VOICEMAILS:
                case STATUS:
                    return new UriData(uri, uriType, null, sourcePackage);
                case VOICEMAILS_ID:
                case STATUS_ID:
                    return new UriData(uri, uriType, segments.get(1), sourcePackage);
                case NO_MATCH:
                    throw new IllegalArgumentException("Invalid URI: " + uri);
                default:
                    throw new IllegalStateException("Impossible, all cases are covered");
            }
        }

        private static TypedUriMatcherImpl<VoicemailUriType> createUriMatcher() {
            return new TypedUriMatcherImpl<VoicemailUriType>(
                    VoicemailContract.AUTHORITY, VoicemailUriType.values());
        }
    }

    @Override
    // VoicemailTable.DelegateHelper interface.
    public void checkAndAddSourcePackageIntoValues(UriData uriData, ContentValues values) {
        // If content values don't contain the provider, calculate the right provider to use.
        if (!values.containsKey(SOURCE_PACKAGE_FIELD)) {
            String provider = uriData.hasSourcePackage() ?
                    uriData.getSourcePackage() : getInjectedCallingPackage();
            values.put(SOURCE_PACKAGE_FIELD, provider);
        }

        // You must have access to the provider given in values.
        if (!mVoicemailPermissions.callerHasWriteAccess(getCallingPackage())) {
            checkPackagesMatch(getInjectedCallingPackage(),
                    values.getAsString(VoicemailContract.SOURCE_PACKAGE_FIELD),
                    uriData.getUri());
        }
    }

    /**
     * Checks that the source_package field is same in uriData and ContentValues, if it happens
     * to be set in both.
     */
    private void checkSourcePackageSameIfSet(UriData uriData, ContentValues values) {
        if (uriData.hasSourcePackage() && values.containsKey(SOURCE_PACKAGE_FIELD)) {
            if (!uriData.getSourcePackage().equals(values.get(SOURCE_PACKAGE_FIELD))) {
                throw new SecurityException(
                        "source_package in URI was " + uriData.getSourcePackage() +
                        " but doesn't match source_package in ContentValues which was "
                        + values.get(SOURCE_PACKAGE_FIELD));
            }
        }
    }

    @Override
    /** Implementation of  {@link VoicemailTable.DelegateHelper#openDataFile(UriData, String)} */
    public ParcelFileDescriptor openDataFile(UriData uriData, String mode)
            throws FileNotFoundException {
        return openFileHelper(uriData.getUri(), mode);
    }

    /**
     * Ensures that the caller has the permissions to perform a query/read operation, and
     * then returns the structured representation {@link UriData} of the supplied uri.
     */
    private UriData checkPermissionsAndCreateUriDataForRead(Uri uri) {
        // If the caller has been explicitly granted read permission to this URI then no need to
        // check further.
        if (ContactsPermissions.hasCallerUriPermission(
                getContext(), uri, Intent.FLAG_GRANT_READ_URI_PERMISSION)) {
            return UriData.createUriData(uri);
        }

        if (mVoicemailPermissions.callerHasReadAccess(getCallingPackage())) {
            return UriData.createUriData(uri);
        }

        return checkPermissionsAndCreateUriData(uri, true);
    }

    /**
     * Performs necessary voicemail permission checks common to all operations and returns
     * the structured representation, {@link UriData}, of the supplied uri.
     */
    private UriData checkPermissionsAndCreateUriData(Uri uri, boolean read) {
        UriData uriData = UriData.createUriData(uri);
        if (!hasReadWritePermission(read)) {
            mVoicemailPermissions.checkCallerHasOwnVoicemailAccess();
            checkPackagePermission(uriData);
        }
        return uriData;
    }

    /**
     * Ensures that the caller has the permissions to perform an update/delete operation, and
     * then returns the structured representation {@link UriData} of the supplied uri.
     * Also does a permission check on the ContentValues.
     */
    private UriData checkPermissionsAndCreateUriDataForWrite(Uri uri, ContentValues... valuesArray) {
        UriData uriData = checkPermissionsAndCreateUriData(uri, false);
        for (ContentValues values : valuesArray) {
            checkSourcePackageSameIfSet(uriData, values);
        }
        return uriData;
    }

    /**
     * Checks that the callingPackage is same as voicemailSourcePackage. Throws {@link
     * SecurityException} if they don't match.
     */
    private final void checkPackagesMatch(String callingPackage, String voicemailSourcePackage,
            Uri uri) {
        if (!voicemailSourcePackage.equals(callingPackage)) {
            String errorMsg = String.format("Permission denied for URI: %s\n. " +
                    "Package %s cannot perform this operation for %s. Requires %s permission.",
                    uri, callingPackage, voicemailSourcePackage,
                    android.Manifest.permission.WRITE_VOICEMAIL);
            throw new SecurityException(errorMsg);
        }
    }

    /**
     * Checks that either the caller has the MANAGE_VOICEMAIL permission,
     * or has the ADD_VOICEMAIL permission and is using a URI that matches
     * /voicemail/?source_package=[source-package] where [source-package] is the same as the calling
     * package.
     *
     * @throws SecurityException if the check fails.
     */
    private void checkPackagePermission(UriData uriData) {
        if (!mVoicemailPermissions.callerHasWriteAccess(getCallingPackage())) {
            if (!uriData.hasSourcePackage()) {
                // You cannot have a match if this is not a provider URI.
                throw new SecurityException(String.format(
                        "Provider %s does not have %s permission." +
                                "\nPlease set query parameter '%s' in the URI.\nURI: %s",
                        getInjectedCallingPackage(), android.Manifest.permission.WRITE_VOICEMAIL,
                        VoicemailContract.PARAM_KEY_SOURCE_PACKAGE, uriData.getUri()));
            }
            checkPackagesMatch(getInjectedCallingPackage(), uriData.getSourcePackage(),
                    uriData.getUri());
        }
    }

    @VisibleForTesting
    String getInjectedCallingPackage() {
        return super.getCallingPackage();
    }

    /**
     * Creates a clause to restrict the selection to the calling provider or null if the caller has
     * access to all data.
     */
    private String getPackageRestrictionClause(boolean isQuery) {
        if (hasReadWritePermission(isQuery)) {
            return null;
        }
        return getEqualityClause(Voicemails.SOURCE_PACKAGE, getInjectedCallingPackage());
    }

    /**
     * Whether or not the calling package has the appropriate read/write permission. The user
     * selected default and/or system dialers are always allowed to read and write to the
     * VoicemailContentProvider.
     *
     * @param read Whether or not this operation is a read
     *
     * @return True if the package has the permission required to perform the read/write operation
     */
    private boolean hasReadWritePermission(boolean read) {
        return read ? mVoicemailPermissions.callerHasReadAccess(getCallingPackage()) :
            mVoicemailPermissions.callerHasWriteAccess(getCallingPackage());
    }

    /** Remove all records from a given source package. */
    public void removeBySourcePackage(String packageName) {
        delete(Voicemails.buildSourceUri(packageName), null, null);
        delete(Status.buildSourceUri(packageName), null, null);
    }

    @VisibleForTesting
    void performBackgroundTask(int task, Object arg) {
        switch (task) {
            case BACKGROUND_TASK_SCAN_STALE_PACKAGES:
                removeStalePackages();
                break;
        }
    }

    /**
     * Remove all records made by packages that no longer exist.
     */
    private void removeStalePackages() {
        if (VERBOSE_LOGGING) {
            Log.v(TAG, "scanStalePackages start");
        }

        // Make sure all source tables still exists.

        // First, list all source packages.
        final ArraySet<String> packages = mVoicemailContentTable.getSourcePackages();
        packages.addAll(mVoicemailStatusTable.getSourcePackages());

        // Remove the ones that still exist.
        for (int i = packages.size() - 1; i >= 0; i--) {
            final String pkg = packages.valueAt(i);
            final boolean installed = PackageUtils.isPackageInstalled(getContext(), pkg);
            if (VERBOSE_LOGGING) {
                Log.v(TAG, "  " + pkg + (installed ? " installed" : " removed"));
            }
            if (!installed) {
                removeBySourcePackage(pkg);
            }
        }

        if (VERBOSE_LOGGING) {
            Log.v(TAG, "scanStalePackages finish");
        }
    }
}
