/*
 * Copyright (C) 2015 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.server.devicepolicy;

import static org.mockito.Mockito.mock;

import android.content.BroadcastReceiver;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.os.Bundle;
import android.os.Handler;
import android.os.UserHandle;
import android.os.UserManagerInternal;
import android.test.mock.MockContext;
import android.util.ArrayMap;

import org.junit.Assert;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * Context used throughout DPMS tests.
 */
public class DpmMockContext extends MockContext {
    /**
     * User-id of a non-system user we use throughout unit tests.
     */
    public static final int CALLER_USER_HANDLE = 20;

    /**
     * UID corresponding to {@link #CALLER_USER_HANDLE}.
     */
    public static final int CALLER_UID = UserHandle.getUid(CALLER_USER_HANDLE, 20123);

    /**
     * UID used when a caller is on the system user.
     */
    public static final int CALLER_SYSTEM_USER_UID = 20321;

    /**
     * PID of the caller.
     */
    public static final int CALLER_PID = 22222;

    /**
     * UID of the system server.
     */
    public static final int SYSTEM_UID = android.os.Process.SYSTEM_UID;

    /**
     * PID of the system server.
     */
    public static final int SYSTEM_PID = 11111;

    public static final String ANOTHER_PACKAGE_NAME = "com.another.package.name";
    public static final int ANOTHER_UID = UserHandle.getUid(UserHandle.USER_SYSTEM, 18434);

    private final MockSystemServices mMockSystemServices;

    public static class MockBinder {
        public int callingUid = CALLER_UID;
        public int callingPid = CALLER_PID;
        public final Map<Integer, List<String>> callingPermissions = new ArrayMap<>();

        public long clearCallingIdentity() {
            final long token = (((long) callingUid) << 32) | (callingPid);
            callingUid = SYSTEM_UID;
            callingPid = SYSTEM_PID;
            return token;
        }

        public void restoreCallingIdentity(long token) {
            callingUid = (int) (token >> 32);
            callingPid = (int) token;
        }

        public int getCallingUid() {
            return callingUid;
        }

        public int getCallingPid() {
            return callingPid;
        }

        public UserHandle getCallingUserHandle() {
            return new UserHandle(UserHandle.getUserId(getCallingUid()));
        }

        public boolean isCallerUidMyUid() {
            return callingUid == SYSTEM_UID;
        }
    }

    private final Context realTestContext;

    /**
     * Use this instance to verify unimplemented methods such as {@link #sendBroadcast}.
     * (Spying on {@code this} instance will confuse mockito somehow and I got weired "wrong number
     * of arguments" exceptions.)
     */
    public final Context spiedContext;

    public final MockBinder binder;
    public final Resources resources;

    /** TODO: Migrate everything to use {@link #permissions} to avoid confusion. */
    @Deprecated
    public final List<String> callerPermissions = new ArrayList<>();

    /** Less confusing alias for {@link #callerPermissions}. */
    public final List<String> permissions = callerPermissions;

    public String packageName = null;

    public ApplicationInfo applicationInfo = null;

    public DpmMockContext(MockSystemServices mockSystemServices, Context context) {
        mMockSystemServices = mockSystemServices;
        realTestContext = context;

        binder = new MockBinder();
        resources = mock(Resources.class);
        spiedContext = mock(Context.class);
    }

    @Override
    public Resources getResources() {
        return resources;
    }

    @Override
    public Resources.Theme getTheme() {
        return spiedContext.getTheme();
    }

    @Override
    public String getPackageName() {
        if (packageName != null) {
            return packageName;
        }
        return super.getPackageName();
    }

    @Override
    public ApplicationInfo getApplicationInfo() {
        if (applicationInfo != null) {
            return applicationInfo;
        }
        return super.getApplicationInfo();
    }

    @Override
    public Object getSystemService(String name) {
        switch (name) {
            case Context.ALARM_SERVICE:
                return mMockSystemServices.alarmManager;
            case Context.USER_SERVICE:
                return mMockSystemServices.userManager;
            case Context.POWER_SERVICE:
                return mMockSystemServices.powerManager;
            case Context.WIFI_SERVICE:
                return mMockSystemServices.wifiManager;
            case Context.ACCOUNT_SERVICE:
                return mMockSystemServices.accountManager;
        }
        throw new UnsupportedOperationException();
    }

    @Override
    public String getSystemServiceName(Class<?> serviceClass) {
        return realTestContext.getSystemServiceName(serviceClass);
    }

    @Override
    public PackageManager getPackageManager() {
        return mMockSystemServices.packageManager;
    }

    public UserManagerInternal getUserManagerInternal() {
        return mMockSystemServices.userManagerInternal;
    }

    @Override
    public void enforceCallingOrSelfPermission(String permission, String message) {
        if (UserHandle.isSameApp(binder.getCallingUid(), SYSTEM_UID)) {
            return; // Assume system has all permissions.
        }
        List<String> permissions = binder.callingPermissions.get(binder.getCallingUid());
        if (permissions == null) {
            // TODO: delete the following line. to do this without breaking any tests, first it's
            //       necessary to remove all tests that set it directly.
            permissions = callerPermissions;
            //            throw new UnsupportedOperationException(
            //                    "Caller UID " + binder.getCallingUid() + " doesn't exist");
        }
        if (!permissions.contains(permission)) {
            throw new SecurityException("Caller doesn't have " + permission + " : " + message);
        }
    }

    @Override
    public void sendBroadcast(Intent intent) {
        spiedContext.sendBroadcast(intent);
    }

    @Override
    public void sendBroadcast(Intent intent, String receiverPermission) {
        spiedContext.sendBroadcast(intent, receiverPermission);
    }

    @Override
    public void sendBroadcastMultiplePermissions(Intent intent, String[] receiverPermissions) {
        spiedContext.sendBroadcastMultiplePermissions(intent, receiverPermissions);
    }

    @Override
    public void sendBroadcastAsUserMultiplePermissions(Intent intent, UserHandle user,
            String[] receiverPermissions) {
        spiedContext.sendBroadcastAsUserMultiplePermissions(intent, user, receiverPermissions);
    }

    @Override
    public void sendBroadcast(Intent intent, String receiverPermission, Bundle options) {
        spiedContext.sendBroadcast(intent, receiverPermission, options);
    }

    @Override
    public void sendBroadcast(Intent intent, String receiverPermission, int appOp) {
        spiedContext.sendBroadcast(intent, receiverPermission, appOp);
    }

    @Override
    public void sendOrderedBroadcast(Intent intent, String receiverPermission) {
        spiedContext.sendOrderedBroadcast(intent, receiverPermission);
    }

    @Override
    public void sendOrderedBroadcast(Intent intent, String receiverPermission,
            BroadcastReceiver resultReceiver, Handler scheduler, int initialCode,
            String initialData, Bundle initialExtras) {
        spiedContext.sendOrderedBroadcast(intent, receiverPermission, resultReceiver, scheduler,
                initialCode, initialData, initialExtras);
    }

    @Override
    public void sendOrderedBroadcast(Intent intent, String receiverPermission, Bundle options,
            BroadcastReceiver resultReceiver, Handler scheduler, int initialCode,
            String initialData, Bundle initialExtras) {
        spiedContext.sendOrderedBroadcast(intent, receiverPermission, options, resultReceiver,
                scheduler,
                initialCode, initialData, initialExtras);
    }

    @Override
    public void sendOrderedBroadcast(Intent intent, String receiverPermission, int appOp,
            BroadcastReceiver resultReceiver, Handler scheduler, int initialCode,
            String initialData, Bundle initialExtras) {
        spiedContext.sendOrderedBroadcast(intent, receiverPermission, appOp, resultReceiver,
                scheduler,
                initialCode, initialData, initialExtras);
    }

    @Override
    public void sendBroadcastAsUser(Intent intent, UserHandle user) {
        if (binder.callingPid != SYSTEM_PID) {
            // Unless called as the system process, can only call if the target user is the
            // calling user.
            // (The actual check is more complex; we may need to change it later.)
            Assert.assertEquals(UserHandle.getUserId(binder.getCallingUid()), user.getIdentifier());
        }

        spiedContext.sendBroadcastAsUser(intent, user);
    }

    @Override
    public void sendBroadcastAsUser(Intent intent, UserHandle user, String receiverPermission) {
        spiedContext.sendBroadcastAsUser(intent, user, receiverPermission);
    }

    @Override
    public void sendBroadcastAsUser(Intent intent, UserHandle user, String receiverPermission,
            int appOp) {
        spiedContext.sendBroadcastAsUser(intent, user, receiverPermission, appOp);
    }

    @Override
    public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user,
            String receiverPermission, BroadcastReceiver resultReceiver, Handler scheduler,
            int initialCode, String initialData, Bundle initialExtras) {
        spiedContext.sendOrderedBroadcastAsUser(intent, user, receiverPermission, resultReceiver,
                scheduler, initialCode, initialData, initialExtras);
        resultReceiver.onReceive(spiedContext, intent);
    }

    @Override
    public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user,
            String receiverPermission, int appOp, BroadcastReceiver resultReceiver,
            Handler scheduler, int initialCode, String initialData, Bundle initialExtras) {
        spiedContext.sendOrderedBroadcastAsUser(intent, user, receiverPermission, appOp,
                resultReceiver,
                scheduler, initialCode, initialData, initialExtras);
    }

    @Override
    public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user,
            String receiverPermission, int appOp, Bundle options, BroadcastReceiver resultReceiver,
            Handler scheduler, int initialCode, String initialData, Bundle initialExtras) {
        spiedContext.sendOrderedBroadcastAsUser(intent, user, receiverPermission, appOp, options,
                resultReceiver, scheduler, initialCode, initialData, initialExtras);
    }

    @Override
    public void sendStickyBroadcast(Intent intent) {
        spiedContext.sendStickyBroadcast(intent);
    }

    @Override
    public void sendStickyOrderedBroadcast(Intent intent, BroadcastReceiver resultReceiver,
            Handler scheduler, int initialCode, String initialData, Bundle initialExtras) {
        spiedContext.sendStickyOrderedBroadcast(intent, resultReceiver, scheduler, initialCode,
                initialData, initialExtras);
    }

    @Override
    public void removeStickyBroadcast(Intent intent) {
        spiedContext.removeStickyBroadcast(intent);
    }

    @Override
    public void sendStickyBroadcastAsUser(Intent intent, UserHandle user) {
        spiedContext.sendStickyBroadcastAsUser(intent, user);
    }

    @Override
    public void sendStickyOrderedBroadcastAsUser(Intent intent, UserHandle user,
            BroadcastReceiver resultReceiver, Handler scheduler, int initialCode,
            String initialData, Bundle initialExtras) {
        spiedContext.sendStickyOrderedBroadcastAsUser(intent, user, resultReceiver, scheduler, initialCode,
                initialData, initialExtras);
    }

    @Override
    public void removeStickyBroadcastAsUser(Intent intent, UserHandle user) {
        spiedContext.removeStickyBroadcastAsUser(intent, user);
    }

    @Override
    public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
        mMockSystemServices.registerReceiver(receiver, filter, null);
        return spiedContext.registerReceiver(receiver, filter);
    }

    @Override
    public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
            String broadcastPermission, Handler scheduler) {
        mMockSystemServices.registerReceiver(receiver, filter, scheduler);
        return spiedContext.registerReceiver(receiver, filter, broadcastPermission, scheduler);
    }

    @Override
    public Intent registerReceiverAsUser(BroadcastReceiver receiver, UserHandle user,
            IntentFilter filter, String broadcastPermission, Handler scheduler) {
        mMockSystemServices.registerReceiver(receiver, filter, scheduler);
        return spiedContext.registerReceiverAsUser(receiver, user, filter, broadcastPermission,
                scheduler);
    }

    @Override
    public void unregisterReceiver(BroadcastReceiver receiver) {
        mMockSystemServices.unregisterReceiver(receiver);
        spiedContext.unregisterReceiver(receiver);
    }

    @Override
    public Context createPackageContextAsUser(String packageName, int flags, UserHandle user)
            throws PackageManager.NameNotFoundException {
        return mMockSystemServices.createPackageContextAsUser(packageName, flags, user);
    }

    @Override
    public ContentResolver getContentResolver() {
        return mMockSystemServices.contentResolver;
    }

    @Override
    public int getUserId() {
        return UserHandle.getUserId(binder.getCallingUid());
    }
}
