/*
 * Copyright (C) 2017 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.testing;

import android.content.BroadcastReceiver;
import android.content.ComponentCallbacks;
import android.content.ComponentName;
import android.content.ContentProviderClient;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.net.Uri;
import android.os.Handler;
import android.os.IBinder;
import android.os.UserHandle;
import android.provider.Settings;
import android.util.ArrayMap;
import android.view.LayoutInflater;

import org.junit.rules.TestRule;
import org.junit.rules.TestWatcher;
import org.junit.runner.Description;
import org.junit.runners.model.Statement;

/**
 * A ContextWrapper with utilities specifically designed to make Testing easier.
 *
 * <ul>
 * <li>System services can be mocked out with {@link #addMockSystemService}</li>
 * <li>Service binding can be mocked out with {@link #addMockService}</li>
 * <li>Resources can be mocked out using {@link #getOrCreateTestableResources()}</li>
 * <li>Settings support {@link TestableSettingsProvider}</li>
 * <li>Has support for {@link LeakCheck} for services and receivers</li>
 * </ul>
 *
 * <p>TestableContext should be defined as a rule on your test so it can clean up after itself.
 * Like the following:</p>
 * <pre class="prettyprint">
 * &#064;Rule
 * public final TestableContext mContext = new TestableContext(InstrumentationRegister.getContext());
 * </pre>
 */
public class TestableContext extends ContextWrapper implements TestRule {

    private final TestableContentResolver mTestableContentResolver;
    private final TestableSettingsProvider mSettingsProvider;

    private ArrayMap<String, Object> mMockSystemServices;
    private ArrayMap<ComponentName, IBinder> mMockServices;
    private ArrayMap<ServiceConnection, ComponentName> mActiveServices;

    private PackageManager mMockPackageManager;
    private LeakCheck.Tracker mReceiver;
    private LeakCheck.Tracker mService;
    private LeakCheck.Tracker mComponent;
    private TestableResources mTestableResources;
    private TestablePermissions mTestablePermissions;

    public TestableContext(Context base) {
        this(base, null);
    }

    public TestableContext(Context base, LeakCheck check) {
        super(base);
        mTestableContentResolver = new TestableContentResolver(base);
        ContentProviderClient settings = base.getContentResolver()
                .acquireContentProviderClient(Settings.AUTHORITY);
        mSettingsProvider = TestableSettingsProvider.getFakeSettingsProvider(settings);
        mTestableContentResolver.addProvider(Settings.AUTHORITY, mSettingsProvider);
        mSettingsProvider.clearValuesAndCheck(TestableContext.this);
        mReceiver = check != null ? check.getTracker("receiver") : null;
        mService = check != null ? check.getTracker("service") : null;
        mComponent = check != null ? check.getTracker("component") : null;
    }

    public void setMockPackageManager(PackageManager mock) {
        mMockPackageManager = mock;
    }

    @Override
    public PackageManager getPackageManager() {
        if (mMockPackageManager != null) {
            return mMockPackageManager;
        }
        return super.getPackageManager();
    }

    /**
     * Makes sure the resources being returned by this TestableContext are a version of
     * TestableResources.
     * @see #getResources()
     */
    public void ensureTestableResources() {
        if (mTestableResources == null) {
            mTestableResources = new TestableResources(super.getResources());
        }
    }

    /**
     * Get (and create if necessary) {@link TestableResources} for this TestableContext.
     */
    public TestableResources getOrCreateTestableResources() {
        ensureTestableResources();
        return mTestableResources;
    }

    /**
     * Returns a Resources instance for the test.
     *
     * By default this returns the same resources object that would come from the
     * {@link ContextWrapper}, but if {@link #ensureTestableResources()} or
     * {@link #getOrCreateTestableResources()} has been called, it will return resources gotten from
     * {@link TestableResources}.
     */
    @Override
    public Resources getResources() {
        return mTestableResources != null ? mTestableResources.getResources()
                : super.getResources();
    }

    /**
     * @see #getSystemService(String)
     */
    public <T> void addMockSystemService(Class<T> service, T mock) {
        addMockSystemService(getSystemServiceName(service), mock);
    }

    /**
     * @see #getSystemService(String)
     */
    public void addMockSystemService(String name, Object service) {
        if (mMockSystemServices == null) mMockSystemServices = new ArrayMap<>();
        mMockSystemServices.put(name, service);
    }

    /**
     * If a matching mock service has been added through {@link #addMockSystemService} then
     * that will be returned, otherwise the real service will be acquired from the base
     * context.
     */
    @Override
    public Object getSystemService(String name) {
        if (mMockSystemServices != null && mMockSystemServices.containsKey(name)) {
            return mMockSystemServices.get(name);
        }
        if (name.equals(LAYOUT_INFLATER_SERVICE)) {
            return getBaseContext().getSystemService(LayoutInflater.class).cloneInContext(this);
        }
        return super.getSystemService(name);
    }

    TestableSettingsProvider getSettingsProvider() {
        return mSettingsProvider;
    }

    @Override
    public TestableContentResolver getContentResolver() {
        return mTestableContentResolver;
    }

    /**
     * Will always return itself for a TestableContext to ensure the testable effects extend
     * to the application context.
     */
    @Override
    public Context getApplicationContext() {
        // Return this so its always a TestableContext.
        return this;
    }

    @Override
    public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
        if (mReceiver != null) mReceiver.getLeakInfo(receiver).addAllocation(new Throwable());
        return super.registerReceiver(receiver, filter);
    }

    @Override
    public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
            String broadcastPermission, Handler scheduler) {
        if (mReceiver != null) mReceiver.getLeakInfo(receiver).addAllocation(new Throwable());
        return super.registerReceiver(receiver, filter, broadcastPermission, scheduler);
    }

    @Override
    public Intent registerReceiverAsUser(BroadcastReceiver receiver, UserHandle user,
            IntentFilter filter, String broadcastPermission, Handler scheduler) {
        if (mReceiver != null) mReceiver.getLeakInfo(receiver).addAllocation(new Throwable());
        return super.registerReceiverAsUser(receiver, user, filter, broadcastPermission,
                scheduler);
    }

    @Override
    public void unregisterReceiver(BroadcastReceiver receiver) {
        if (mReceiver != null) mReceiver.getLeakInfo(receiver).clearAllocations();
        super.unregisterReceiver(receiver);
    }

    /**
     * Adds a mock service to be connected to by a bindService call.
     * <p>
     *     Normally a TestableContext will pass through all bind requests to the base context
     *     but when addMockService has been called for a ComponentName being bound, then
     *     TestableContext will immediately trigger a {@link ServiceConnection#onServiceConnected}
     *     with the specified service, and will call {@link ServiceConnection#onServiceDisconnected}
     *     when the service is unbound.
     * </p>
     */
    public void addMockService(ComponentName component, IBinder service) {
        if (mMockServices == null) mMockServices = new ArrayMap<>();
        mMockServices.put(component, service);
    }

    /**
     * @see #addMockService(ComponentName, IBinder)
     */
    @Override
    public boolean bindService(Intent service, ServiceConnection conn, int flags) {
        if (mService != null) mService.getLeakInfo(conn).addAllocation(new Throwable());
        if (checkMocks(service.getComponent(), conn)) return true;
        return super.bindService(service, conn, flags);
    }

    /**
     * @see #addMockService(ComponentName, IBinder)
     */
    @Override
    public boolean bindServiceAsUser(Intent service, ServiceConnection conn, int flags,
            Handler handler, UserHandle user) {
        if (mService != null) mService.getLeakInfo(conn).addAllocation(new Throwable());
        if (checkMocks(service.getComponent(), conn)) return true;
        return super.bindServiceAsUser(service, conn, flags, handler, user);
    }

    /**
     * @see #addMockService(ComponentName, IBinder)
     */
    @Override
    public boolean bindServiceAsUser(Intent service, ServiceConnection conn, int flags,
            UserHandle user) {
        if (mService != null) mService.getLeakInfo(conn).addAllocation(new Throwable());
        if (checkMocks(service.getComponent(), conn)) return true;
        return super.bindServiceAsUser(service, conn, flags, user);
    }

    private boolean checkMocks(ComponentName component, ServiceConnection conn) {
        if (mMockServices != null && component != null && mMockServices.containsKey(component)) {
            if (mActiveServices == null) mActiveServices = new ArrayMap<>();
            mActiveServices.put(conn, component);
            conn.onServiceConnected(component, mMockServices.get(component));
            return true;
        }
        return false;
    }

    /**
     * @see #addMockService(ComponentName, IBinder)
     */
    @Override
    public void unbindService(ServiceConnection conn) {
        if (mService != null) mService.getLeakInfo(conn).clearAllocations();
        if (mActiveServices != null && mActiveServices.containsKey(conn)) {
            conn.onServiceDisconnected(mActiveServices.get(conn));
            mActiveServices.remove(conn);
            return;
        }
        super.unbindService(conn);
    }

    /**
     * Check if the TestableContext has a mock binding for a specified component. Will return
     * true between {@link ServiceConnection#onServiceConnected} and
     * {@link ServiceConnection#onServiceDisconnected} callbacks for a mock service.
     *
     * @see #addMockService(ComponentName, IBinder)
     */
    public boolean isBound(ComponentName component) {
        return mActiveServices != null && mActiveServices.containsValue(component);
    }

    @Override
    public void registerComponentCallbacks(ComponentCallbacks callback) {
        if (mComponent != null) mComponent.getLeakInfo(callback).addAllocation(new Throwable());
        super.registerComponentCallbacks(callback);
    }

    @Override
    public void unregisterComponentCallbacks(ComponentCallbacks callback) {
        if (mComponent != null) mComponent.getLeakInfo(callback).clearAllocations();
        super.unregisterComponentCallbacks(callback);
    }

    public TestablePermissions getTestablePermissions() {
        if (mTestablePermissions == null) {
            mTestablePermissions = new TestablePermissions();
        }
        return mTestablePermissions;
    }

    @Override
    public int checkCallingOrSelfPermission(String permission) {
        if (mTestablePermissions != null && mTestablePermissions.wantsCall(permission)) {
            return mTestablePermissions.check(permission);
        }
        return super.checkCallingOrSelfPermission(permission);
    }

    @Override
    public int checkCallingPermission(String permission) {
        if (mTestablePermissions != null && mTestablePermissions.wantsCall(permission)) {
            return mTestablePermissions.check(permission);
        }
        return super.checkCallingPermission(permission);
    }

    @Override
    public int checkPermission(String permission, int pid, int uid) {
        if (mTestablePermissions != null && mTestablePermissions.wantsCall(permission)) {
            return mTestablePermissions.check(permission);
        }
        return super.checkPermission(permission, pid, uid);
    }

    @Override
    public int checkPermission(String permission, int pid, int uid, IBinder callerToken) {
        if (mTestablePermissions != null && mTestablePermissions.wantsCall(permission)) {
            return mTestablePermissions.check(permission);
        }
        return super.checkPermission(permission, pid, uid, callerToken);
    }

    @Override
    public int checkSelfPermission(String permission) {
        if (mTestablePermissions != null && mTestablePermissions.wantsCall(permission)) {
            return mTestablePermissions.check(permission);
        }
        return super.checkSelfPermission(permission);
    }

    @Override
    public void enforceCallingOrSelfPermission(String permission, String message) {
        if (mTestablePermissions != null && mTestablePermissions.wantsCall(permission)) {
            mTestablePermissions.enforce(permission);
        } else {
            super.enforceCallingOrSelfPermission(permission, message);
        }
    }

    @Override
    public void enforceCallingPermission(String permission, String message) {
        if (mTestablePermissions != null && mTestablePermissions.wantsCall(permission)) {
            mTestablePermissions.enforce(permission);
        } else {
            super.enforceCallingPermission(permission, message);
        }
    }

    @Override
    public void enforcePermission(String permission, int pid, int uid, String message) {
        if (mTestablePermissions != null && mTestablePermissions.wantsCall(permission)) {
            mTestablePermissions.enforce(permission);
        } else {
            super.enforcePermission(permission, pid, uid, message);
        }
    }

    @Override
    public int checkCallingOrSelfUriPermission(Uri uri, int modeFlags) {
        if (mTestablePermissions != null && mTestablePermissions.wantsCall(uri)) {
            return mTestablePermissions.check(uri, modeFlags);
        }
        return super.checkCallingOrSelfUriPermission(uri, modeFlags);
    }

    @Override
    public int checkCallingUriPermission(Uri uri, int modeFlags) {
        if (mTestablePermissions != null && mTestablePermissions.wantsCall(uri)) {
            return mTestablePermissions.check(uri, modeFlags);
        }
        return super.checkCallingUriPermission(uri, modeFlags);
    }

    @Override
    public void enforceCallingOrSelfUriPermission(Uri uri, int modeFlags, String message) {
        if (mTestablePermissions != null && mTestablePermissions.wantsCall(uri)) {
            mTestablePermissions.enforce(uri, modeFlags);
        } else {
            super.enforceCallingOrSelfUriPermission(uri, modeFlags, message);
        }
    }

    @Override
    public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
        if (mTestablePermissions != null && mTestablePermissions.wantsCall(uri)) {
            return mTestablePermissions.check(uri, modeFlags);
        }
        return super.checkUriPermission(uri, pid, uid, modeFlags);
    }

    @Override
    public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags, IBinder callerToken) {
        if (mTestablePermissions != null && mTestablePermissions.wantsCall(uri)) {
            return mTestablePermissions.check(uri, modeFlags);
        }
        return super.checkUriPermission(uri, pid, uid, modeFlags, callerToken);
    }

    @Override
    public int checkUriPermission(Uri uri, String readPermission, String writePermission, int pid,
            int uid, int modeFlags) {
        if (mTestablePermissions != null && mTestablePermissions.wantsCall(uri)) {
            return mTestablePermissions.check(uri, modeFlags);
        }
        return super.checkUriPermission(uri, readPermission, writePermission, pid, uid, modeFlags);
    }

    @Override
    public void enforceCallingUriPermission(Uri uri, int modeFlags, String message) {
        if (mTestablePermissions != null && mTestablePermissions.wantsCall(uri)) {
            mTestablePermissions.enforce(uri, modeFlags);
        } else {
            super.enforceCallingUriPermission(uri, modeFlags, message);
        }
    }

    @Override
    public void enforceUriPermission(Uri uri, int pid, int uid, int modeFlags, String message) {
        if (mTestablePermissions != null && mTestablePermissions.wantsCall(uri)) {
            mTestablePermissions.enforce(uri, modeFlags);
        } else {
            super.enforceUriPermission(uri, pid, uid, modeFlags, message);
        }
    }

    @Override
    public void enforceUriPermission(Uri uri, String readPermission, String writePermission,
            int pid, int uid, int modeFlags, String message) {
        if (mTestablePermissions != null && mTestablePermissions.wantsCall(uri)) {
            mTestablePermissions.enforce(uri, modeFlags);
        } else {
            super.enforceUriPermission(uri, readPermission, writePermission, pid, uid, modeFlags,
                    message);
        }
    }

    @Override
    public Statement apply(Statement base, Description description) {
        return new TestWatcher() {
            @Override
            protected void succeeded(Description description) {
                mSettingsProvider.clearValuesAndCheck(TestableContext.this);
            }

            @Override
            protected void failed(Throwable e, Description description) {
                mSettingsProvider.clearValuesAndCheck(TestableContext.this);
            }
        }.apply(base, description);
    }
}
