/*
 * Copyright (C) 2021 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.bedstead.dpmwrapper;

import static android.Manifest.permission.INTERACT_ACROSS_USERS;

import static com.android.bedstead.dpmwrapper.DataFormatter.addArg;
import static com.android.bedstead.dpmwrapper.DataFormatter.getArg;
import static com.android.bedstead.dpmwrapper.Utils.ACTION_WRAPPED_MANAGER_CALL;
import static com.android.bedstead.dpmwrapper.Utils.EXTRA_CLASS;
import static com.android.bedstead.dpmwrapper.Utils.EXTRA_METHOD;
import static com.android.bedstead.dpmwrapper.Utils.EXTRA_NUMBER_ARGS;
import static com.android.bedstead.dpmwrapper.Utils.VERBOSE;
import static com.android.bedstead.dpmwrapper.Utils.getHandler;

import android.annotation.Nullable;
import android.app.admin.DevicePolicyManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.os.HardwarePropertiesManager;
import android.os.UserHandle;
import android.os.UserManager;
import android.util.Log;

import org.mockito.stubbing.Answer;

import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Locale;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;

//TODO(b/176993670): STOPSHIP - it currently uses ordered broadcasts and a Mockito spy to implement
//the IPC between users, but before S is shipped it should be changed to use the connected apps SDK
//or the new CTS infrastructure.
/**
 * Class used to create to provide a {@link DevicePolicyManager} implementation (and other managers
 * that must be run by the device owner user) that automatically funnels calls between the user
 * running the tests and the user that is the device owner.
 */
public final class TestAppSystemServiceFactory {

    private static final String TAG = TestAppSystemServiceFactory.class.getSimpleName();

    private static final int RESULT_NOT_SENT_TO_ANY_RECEIVER = 108;
    static final int RESULT_OK = 42;
    static final int RESULT_EXCEPTION = 666;

    // Must be high enough to outlast long tests like NetworkLoggingTest, which waits up to
    // 6 minutes for network monitoring events.
    private static final long TIMEOUT_MS = TimeUnit.MINUTES.toMillis(10);

    // Caches whether the package declares the required receiver (otherwise each test would be
    // querying package manager, which is expensive)
    private static final HashMap<String, Boolean> sHasRequiredReceiver = new HashMap<>();

    /**
     * Gets the proper {@link DevicePolicyManager} instance to be used by the test.
     */
    public static DevicePolicyManager getDevicePolicyManager(Context context,
            Class<? extends BroadcastReceiver> receiverClass, boolean forDeviceOwner) {
        return getSystemService(context, DevicePolicyManager.class, receiverClass, forDeviceOwner);
    }

    /**
     * Gets the proper {@link WifiManager} instance to be used by device owner tests.
     */
    public static WifiManager getWifiManager(Context context,
            Class<? extends BroadcastReceiver> receiverClass) {
        return getSystemService(context, WifiManager.class, receiverClass,
                /* forDeviceOwner= */ true);
    }

    /**
     * Gets the proper {@link HardwarePropertiesManager} instance to be used by device owner tests.
     */
    public static HardwarePropertiesManager getHardwarePropertiesManager(Context context,
            Class<? extends BroadcastReceiver> receiverClass) {
        return getSystemService(context, HardwarePropertiesManager.class, receiverClass,
                /* forDeviceOwner= */ true);
    }

    /**
     * Gets the proper {@link UserManager} instance to be used by device owner tests.
     */
    public static UserManager getUserManager(Context context,
            Class<? extends BroadcastReceiver> receiverClass) {
        return getSystemService(context, UserManager.class, receiverClass,
                /* forDeviceOwner= */ true);
    }

    /**
     * Gets the proper {@link GenericManager} instance to be used by the test.
     */
    public static GenericManager getGenericManager(Context context,
            Class<? extends BroadcastReceiver> receiverClass) {
        return getSystemService(context, GenericManager.class, receiverClass,
                /* forDeviceOwner= */ true);
    }

    private static void assertHasRequiredReceiver(Context context) {
        if (!Utils.isHeadlessSystemUserMode()) return;

        String packageName = context.getPackageName();
        Boolean hasIt = sHasRequiredReceiver.get(packageName);
        if (hasIt != null && hasIt) {
            return;
        }
        PackageManager pm = context.getPackageManager();
        Class<?> targetClass = TestAppCallbacksReceiver.class;
        PackageInfo packageInfo;
        try {
            packageInfo = pm.getPackageInfo(packageName, PackageManager.GET_RECEIVERS);
        } catch (NameNotFoundException e) {
            Log.wtf(TAG, "Could not get receivers for " + packageName);
            return;
        }

        int numberReceivers = (packageInfo.receivers == null ? 0 : packageInfo.receivers.length);
        Log.d(TAG, "assertHasRequiredReceiver(" + packageName + "): userId=" + context.getUserId()
                + ", info=" + packageInfo + ", receivers=" + numberReceivers);

        if (packageInfo.receivers != null) {
            for (ActivityInfo receiver : packageInfo.receivers) {
                Log.v(TAG, "checking receiver " + receiver);
                Class<?> receiverClass = null;
                try {
                    receiverClass = Class.forName(receiver.name);
                } catch (ClassNotFoundException e) {
                    Log.e(TAG, "Invalid receiver class on manifest: " + receiver.name);
                    continue;
                }
                if (TestAppCallbacksReceiver.class.isAssignableFrom(receiverClass)) {
                    Log.d(TAG, "Found " + receiverClass.getName() + " on " + packageName);
                    sHasRequiredReceiver.put(packageName, Boolean.TRUE);
                    return;
                }
            }
        }
        if (numberReceivers == 0) {
            // This is happening sometimes on headless system user; most likely it's a permission
            // issue querying pm, but given that the DpmWrapper is temporary and this check is more
            // of a validation to avoid other issues, it's ok to just log...
            Log.wtf(TAG, "Package " + packageName + " has no receivers");
            return;
        }
        fail("Package " + packageName + " has " + numberReceivers + " receivers, but not extends "
                + TestAppCallbacksReceiver.class.getName() + " - did you add one to the manifest?");
    }

    private static <T> T getSystemService(Context context, Class<T> serviceClass,
            Class<? extends BroadcastReceiver> receiverClass, boolean forDeviceOwner) {
        ServiceManagerWrapper<T> wrapper = null;
        Class<?> wrappedClass;

        @SuppressWarnings("unchecked")
        T manager = null;

        if (serviceClass.equals(DevicePolicyManager.class)) {
            wrappedClass = DevicePolicyManager.class;
            @SuppressWarnings("unchecked")
            ServiceManagerWrapper<T> safeCastWrapper =
                    (ServiceManagerWrapper<T>) new DevicePolicyManagerWrapper();
            wrapper = safeCastWrapper;
        } else if (serviceClass.equals(WifiManager.class)) {
            @SuppressWarnings("unchecked")
            ServiceManagerWrapper<T> safeCastWrapper =
                    (ServiceManagerWrapper<T>) new WifiManagerWrapper();
            wrapper = safeCastWrapper;
            wrappedClass = WifiManager.class;
        } else if (serviceClass.equals(HardwarePropertiesManager.class)) {
            @SuppressWarnings("unchecked")
            ServiceManagerWrapper<T> safeCastWrapper =
                    (ServiceManagerWrapper<T>) new HardwarePropertiesManagerWrapper();
            wrapper = safeCastWrapper;
            wrappedClass = HardwarePropertiesManager.class;
        } else if (serviceClass.equals(UserManager.class)) {
            @SuppressWarnings("unchecked")
            ServiceManagerWrapper<T> safeCastWrapper =
                    (ServiceManagerWrapper<T>) new UserManagerWrapper();
            wrapper = safeCastWrapper;
            wrappedClass = UserManager.class;
        } else if (serviceClass.equals(GenericManager.class)) {
            @SuppressWarnings("unchecked")
            ServiceManagerWrapper<T> safeCastWrapper =
                    (ServiceManagerWrapper<T>) new GenericManagerWrapper();
            @SuppressWarnings("unchecked")
            T safeCastManager = (T) new GenericManagerImpl(context);
            wrapper = safeCastWrapper;
            wrappedClass = GenericManager.class;
            manager = safeCastManager;
        } else {
            throw new IllegalArgumentException("invalid service class: " + serviceClass);
        }
        if (manager == null) {
            manager = (T) context.getSystemService(wrappedClass);
        }

        if (manager == null) {
            fail("Could not get a manager of type " + serviceClass);
        }

        if (!forDeviceOwner) return manager;

        assertHasRequiredReceiver(context);

        int userId = context.getUserId();
        if (userId == UserHandle.USER_SYSTEM || !Utils.isHeadlessSystemUserMode()) {
            Log.i(TAG, "get(): returning 'pure' DevicePolicyManager for user " + userId);
            return manager;
        }

        String receiverClassName = receiverClass.getName();
        final String wrappedClassName = wrappedClass.getName();
        if (VERBOSE) {
            Log.v(TAG, "get(): receiverClassName: " + receiverClassName
                    + ", wrappedClassName: " + wrappedClassName);
        }

        Answer<?> answer = (inv) -> {
            Object[] args = inv.getArguments();
            if (VERBOSE) {
                Log.v(TAG, "spying " + inv + " method: " + inv.getMethod());
            } else {
                Log.i(TAG, "spying " + inv.getMethod());
            }
            String methodName = inv.getMethod().getName();
            Intent intent = new Intent(ACTION_WRAPPED_MANAGER_CALL)
                    .setClassName(context, receiverClassName)
                    .putExtra(EXTRA_CLASS, wrappedClassName)
                    .putExtra(EXTRA_METHOD, methodName)
                    .putExtra(EXTRA_NUMBER_ARGS, args.length);
            for (int i = 0; i < args.length; i++) {
                addArg(intent, args, i);
            }

            final CountDownLatch latch = new CountDownLatch(1);
            final AtomicReference<Result> resultRef = new AtomicReference<>();
            BroadcastReceiver myReceiver = new BroadcastReceiver() {
                public void onReceive(Context context, Intent intent) {
                    String action = intent.getAction();
                    if (VERBOSE) {
                        Log.v(TAG, "spy received intent " + action + " for user "
                                + context.getUserId());
                    }
                    Result result = new Result(this);
                    if (VERBOSE) Log.v(TAG, "result:" + result);
                    resultRef.set(result);
                    latch.countDown();
                };

            };
            if (VERBOSE) {
                Log.v(TAG, "Sending ordered broadcast (" + Utils.toString(intent) + ") from user "
                        + userId + " to user " + UserHandle.SYSTEM);
            }

            // NOTE: method below used to be wrapped under runWithShellPermissionIdentity() to get
            // INTERACT_ACROSS_USERS permission, but that's not needed anymore (as the permission
            // is granted by the test. Besides, this class is now also used by DO apps that are not
            // instrumented, so it was removed
            if (context.checkSelfPermission(INTERACT_ACROSS_USERS)
                    != PackageManager.PERMISSION_GRANTED) {
                fail("Package " + context.getPackageName() + " doesn't have "
                        + INTERACT_ACROSS_USERS + " - did you add it to the manifest and called "
                        + "grantDpmWrapper() (for user " + userId + ") in the host-side test?");
            }
            context.sendOrderedBroadcastAsUser(intent,
                    UserHandle.SYSTEM, /* permission= */ null, myReceiver, getHandler(),
                    RESULT_NOT_SENT_TO_ANY_RECEIVER, /* initialData= */ null,
                    /* initialExtras= */ null);

            if (VERBOSE) {
                Log.d(TAG, "Waiting up to " + TIMEOUT_MS + "ms for response on "
                        + Thread.currentThread());
            }
            if (!latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)) {
                fail("Ordered broadcast for %s() not received in %dms", methodName, TIMEOUT_MS);
            }

            Result result = resultRef.get();
            Log.d(TAG, "Received result on user " + userId + ". Code: "
                    + resultCodeToString(result.code));

            if (VERBOSE) {
                // Some results - like network logging events - are quite large
                Log.v(TAG, "Result: " + result);
            }

            switch (result.code) {
                case RESULT_OK:
                    return result.value;
                case RESULT_EXCEPTION:
                    Exception e = (Exception) result.value;
                    throw (e instanceof InvocationTargetException) ? e.getCause() : e;
                case RESULT_NOT_SENT_TO_ANY_RECEIVER:
                    fail("Didn't receive result from ordered broadcast - did you override "
                            + receiverClassName + ".onReceive() to call "
                            + "DeviceOwnerHelper.runManagerMethod()?");
                    return null;
                default:
                    fail("Received invalid result for method %s: %s", methodName, result);
                    return null;
            }
        };

        T spy = wrapper.getWrapper(context, manager, answer);

        return spy;

    }

    static String resultCodeToString(int code) {
        // Can't use DebugUtils.constantToString() because some valus are private
        switch (code) {
            case RESULT_NOT_SENT_TO_ANY_RECEIVER:
                return "RESULT_NOT_SENT_TO_ANY_RECEIVER";
            case RESULT_OK:
                return "RESULT_OK";
            case RESULT_EXCEPTION:
                return "RESULT_EXCEPTION";
            default:
                return "RESULT_UNKNOWN:" + code;
        }
    }

    private static void fail(String template, Object... args) {
        throw new AssertionError(String.format(Locale.ENGLISH, template, args));
    }

    private static final class Result {
        public final int code;
        @Nullable public final String error;
        @Nullable public final Bundle extras;
        @Nullable public final Object value;

        Result(BroadcastReceiver receiver) {
            int resultCode = receiver.getResultCode();
            String data = receiver.getResultData();
            extras = receiver.getResultExtras(/* makeMap= */ true);
            Object parsedValue = null;
            try {
                if (extras != null && !extras.isEmpty()) {
                    Object[] result = new Object[1];
                    int index = 0;
                    getArg(extras, result, /* parameterTypes= */ null, index);
                    parsedValue = result[index];
                }
            } catch (Exception e) {
                Log.e(TAG, "error parsing extras (code=" + resultCode + ", data=" + data, e);
                data = "error parsing extras";
                resultCode = RESULT_EXCEPTION;
            }
            code = resultCode;
            error = data;
            value = parsedValue;
        }

        @Override
        public String toString() {
            return "Result[code=" + resultCodeToString(code) + ", error=" + error
                    + ", extras=" + extras + ", value=" + value + "]";
        }
    }

    abstract static class ServiceManagerWrapper<T> {
        abstract T getWrapper(Context context, T manager, Answer<?> answer);
    }

    private TestAppSystemServiceFactory() {
        throw new UnsupportedOperationException("contains only static methods");
    }
}
