/*
 * Copyright (C) 2009 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 android.test.mock;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.AttributionSource;
import android.content.ContentProvider;
import android.content.ContentProviderOperation;
import android.content.ContentProviderResult;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.content.IContentProvider;
import android.content.Intent;
import android.content.OperationApplicationException;
import android.content.pm.PathPermission;
import android.content.pm.ProviderInfo;
import android.content.res.AssetFileDescriptor;
import android.database.Cursor;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Binder;
import android.os.Bundle;
import android.os.IBinder;
import android.os.ICancellationSignal;
import android.os.ParcelFileDescriptor;
import android.os.RemoteCallback;
import android.os.RemoteException;

import java.io.FileNotFoundException;
import java.util.ArrayList;

/**
 * Mock implementation of ContentProvider.  All methods are non-functional and throw
 * {@link java.lang.UnsupportedOperationException}.  Tests can extend this class to
 * implement behavior needed for tests.
 */
public class MockContentProvider extends ContentProvider {
    /*
     * Note: if you add methods to ContentProvider, you must add similar methods to
     *       MockContentProvider.
     */

    /**
     * IContentProvider that directs all calls to this MockContentProvider.
     */
    private class InversionIContentProvider implements IContentProvider {
        @Override
        public ContentProviderResult[] applyBatch(@NonNull AttributionSource attributionSource,
                String authority, ArrayList<ContentProviderOperation> operations)
                throws RemoteException, OperationApplicationException {
            return MockContentProvider.this.applyBatch(authority, operations);
        }

        @Override
        public int bulkInsert(@NonNull AttributionSource attributionSource, Uri url,
                ContentValues[] initialValues) throws RemoteException {
            return MockContentProvider.this.bulkInsert(url, initialValues);
        }

        @Override
        public int delete(@NonNull AttributionSource attributionSource, Uri url,
                Bundle extras) throws RemoteException {
            return MockContentProvider.this.delete(url, extras);
        }

        @Override
        public String getType(Uri url) throws RemoteException {
            return MockContentProvider.this.getType(url);
        }

        @Override
        public void getTypeAsync(Uri uri, RemoteCallback callback) throws RemoteException {
            MockContentProvider.this.getTypeAsync(uri, callback);
        }

        @Override
        public Uri insert(@NonNull AttributionSource attributionSource, Uri url,
                ContentValues initialValues, Bundle extras) throws RemoteException {
            return MockContentProvider.this.insert(url, initialValues, extras);
        }

        @Override
        public AssetFileDescriptor openAssetFile(@NonNull AttributionSource attributionSource,
                Uri url, String mode, ICancellationSignal signal)
                throws RemoteException, FileNotFoundException {
            return MockContentProvider.this.openAssetFile(url, mode);
        }

        @Override
        public ParcelFileDescriptor openFile(@NonNull AttributionSource attributionSource,
                Uri url, String mode, ICancellationSignal signal)
                throws RemoteException, FileNotFoundException {
            return MockContentProvider.this.openFile(url, mode);
        }

        @Override
        public Cursor query(@NonNull AttributionSource attributionSource, Uri url,
                @Nullable String[] projection, @Nullable Bundle queryArgs,
                @Nullable ICancellationSignal cancellationSignal) throws RemoteException {
            return MockContentProvider.this.query(url, projection, queryArgs, null);
        }

        @Override
        public int update(@NonNull AttributionSource attributionSource, Uri url,
                ContentValues values, Bundle extras) throws RemoteException {
            return MockContentProvider.this.update(url, values, extras);
        }

        @Override
        public Bundle call(@NonNull AttributionSource attributionSource, String authority,
                String method, String request, Bundle args) throws RemoteException {
            return MockContentProvider.this.call(authority, method, request, args);
        }

        @Override
        public IBinder asBinder() {
            return MockContentProvider.this.getIContentProviderBinder();
        }

        @Override
        public String[] getStreamTypes(Uri url, String mimeTypeFilter) throws RemoteException {
            return MockContentProvider.this.getStreamTypes(url, mimeTypeFilter);
        }

        @Override
        public AssetFileDescriptor openTypedAssetFile(
                @NonNull AttributionSource attributionSource, Uri url, String mimeType,
                Bundle opts, ICancellationSignal signal)
                throws RemoteException, FileNotFoundException {
            return MockContentProvider.this.openTypedAssetFile(url, mimeType, opts);
        }

        @Override
        public ICancellationSignal createCancellationSignal() throws RemoteException {
            return null;
        }

        @Override
        public Uri canonicalize(@NonNull AttributionSource attributionSource, Uri uri)
                throws RemoteException {
            return MockContentProvider.this.canonicalize(uri);
        }

        @Override
        public void canonicalizeAsync(@NonNull AttributionSource attributionSource, Uri uri,
                RemoteCallback callback) {
            MockContentProvider.this.canonicalizeAsync(uri, callback);
        }

        @Override
        public Uri uncanonicalize(@NonNull AttributionSource attributionSource, Uri uri)
                throws RemoteException {
            return MockContentProvider.this.uncanonicalize(uri);
        }

        @Override
        public void uncanonicalizeAsync(@NonNull AttributionSource attributionSource, Uri uri,
                RemoteCallback callback) {
            MockContentProvider.this.uncanonicalizeAsync(uri, callback);
        }

        @Override
        public boolean refresh(@NonNull AttributionSource attributionSource, Uri url,
                Bundle args, ICancellationSignal cancellationSignal) throws RemoteException {
            return MockContentProvider.this.refresh(url, args);
        }

        @Override
        public int checkUriPermission(@NonNull AttributionSource attributionSource, Uri uri,
                int uid, int modeFlags) {
            return MockContentProvider.this.checkUriPermission(uri, uid, modeFlags);
        }
    }
    private final InversionIContentProvider mIContentProvider = new InversionIContentProvider();

    /**
     * A constructor using {@link MockContext} instance as a Context in it.
     */
    protected MockContentProvider() {
        super(new MockContext(), "", "", null);
    }

    /**
     * A constructor accepting a Context instance, which is supposed to be the subclasss of
     * {@link MockContext}.
     */
    public MockContentProvider(Context context) {
        super(context, "", "", null);
    }

    /**
     * A constructor which initialize four member variables which
     * {@link android.content.ContentProvider} have internally.
     *
     * @param context A Context object which should be some mock instance (like the
     * instance of {@link android.test.mock.MockContext}).
     * @param readPermission The read permision you want this instance should have in the
     * test, which is available via {@link #getReadPermission()}.
     * @param writePermission The write permission you want this instance should have
     * in the test, which is available via {@link #getWritePermission()}.
     * @param pathPermissions The PathPermissions you want this instance should have
     * in the test, which is available via {@link #getPathPermissions()}.
     */
    public MockContentProvider(Context context,
            String readPermission,
            String writePermission,
            PathPermission[] pathPermissions) {
        super(context, readPermission, writePermission, pathPermissions);
    }

    @Override
    public int delete(Uri uri, String selection, String[] selectionArgs) {
        throw new UnsupportedOperationException("unimplemented mock method");
    }

    @Override
    public String getType(Uri uri) {
        throw new UnsupportedOperationException("unimplemented mock method");
    }

    /**
     * @hide
     */
    @SuppressWarnings("deprecation")
    public void getTypeAsync(Uri uri, RemoteCallback remoteCallback) {
        AsyncTask.SERIAL_EXECUTOR.execute(() -> {
            final Bundle bundle = new Bundle();
            bundle.putString(ContentResolver.REMOTE_CALLBACK_RESULT, getType(uri));
            remoteCallback.sendResult(bundle);
        });
    }

    @Override
    public Uri insert(Uri uri, ContentValues values) {
        throw new UnsupportedOperationException("unimplemented mock method");
    }

    @Override
    public boolean onCreate() {
        throw new UnsupportedOperationException("unimplemented mock method");
    }

    @Override
    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
            String sortOrder) {
        throw new UnsupportedOperationException("unimplemented mock method");
    }

    @Override
    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
        throw new UnsupportedOperationException("unimplemented mock method");
    }

    /**
     * If you're reluctant to implement this manually, please just call super.bulkInsert().
     */
    @Override
    public int bulkInsert(Uri uri, ContentValues[] values) {
        throw new UnsupportedOperationException("unimplemented mock method");
    }

    @Override
    public void attachInfo(Context context, ProviderInfo info) {
        throw new UnsupportedOperationException("unimplemented mock method");
    }

    @Override
    public ContentProviderResult[] applyBatch(ArrayList<ContentProviderOperation> operations) {
        throw new UnsupportedOperationException("unimplemented mock method");
    }

    /**
     * @hide
     */
    @Override
    public Bundle call(String method, String request, Bundle args) {
        throw new UnsupportedOperationException("unimplemented mock method call");
    }

    @Override
    public String[] getStreamTypes(Uri url, String mimeTypeFilter) {
        throw new UnsupportedOperationException("unimplemented mock method call");
    }

    @Override
    public AssetFileDescriptor openTypedAssetFile(Uri url, String mimeType, Bundle opts) {
        throw new UnsupportedOperationException("unimplemented mock method call");
    }

    /**
     * @hide
     */
    @SuppressWarnings("deprecation")
    public void canonicalizeAsync(Uri uri, RemoteCallback callback) {
        AsyncTask.SERIAL_EXECUTOR.execute(() -> {
            final Bundle bundle = new Bundle();
            bundle.putParcelable(ContentResolver.REMOTE_CALLBACK_RESULT, canonicalize(uri));
            callback.sendResult(bundle);
        });
    }

    /**
     * @hide
     */
    @SuppressWarnings("deprecation")
    public void uncanonicalizeAsync(Uri uri, RemoteCallback callback) {
        AsyncTask.SERIAL_EXECUTOR.execute(() -> {
            final Bundle bundle = new Bundle();
            bundle.putParcelable(ContentResolver.REMOTE_CALLBACK_RESULT, uncanonicalize(uri));
            callback.sendResult(bundle);
        });
    }

    /**
     * @hide
     */
    public boolean refresh(Uri url, Bundle args) {
        throw new UnsupportedOperationException("unimplemented mock method call");
    }

    /** {@hide} */
    @Override
    public int checkUriPermission(@NonNull Uri uri, int uid, @Intent.AccessUriMode int modeFlags) {
        throw new UnsupportedOperationException("unimplemented mock method call");
    }

    /**
     * Returns IContentProvider which calls back same methods in this class.
     * By overriding this class, we avoid the mechanism hidden behind ContentProvider
     * (IPC, etc.)
     *
     * @hide
     */
    @Override
    public final IContentProvider getIContentProvider() {
        return mIContentProvider;
    }

    /**
     * @hide
     */
    public IBinder getIContentProviderBinder() {
        return new Binder();
    }

    /**
     * Like {@link #attachInfo(Context, android.content.pm.ProviderInfo)}, but for use
     * when directly instantiating the provider for testing.
     *
     * <p>Provided for use by {@code android.test.ProviderTestCase2} and
     * {@code android.test.RenamingDelegatingContext}.
     *
     * @deprecated Use a mocking framework like <a href="https://github.com/mockito/mockito">Mockito</a>.
     * New tests should be written using the
     * <a href="{@docRoot}tools/testing-support-library/index.html">Android Testing Support Library</a>.
     */
    @Deprecated
    public static void attachInfoForTesting(
            ContentProvider provider, Context context, ProviderInfo providerInfo) {
        provider.attachInfoForTesting(context, providerInfo);
    }
}
