/*
 * Copyright (C) 2019 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.app.role;

import android.Manifest;
import android.annotation.CallbackExecutor;
import android.annotation.NonNull;
import android.annotation.RequiresPermission;
import android.annotation.SystemService;
import android.annotation.UserIdInt;
import android.app.ActivityThread;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
import android.os.RemoteCallback;
import android.os.RemoteException;
import android.util.Log;
import android.util.SparseArray;

import com.android.internal.annotations.GuardedBy;
import com.android.internal.infra.AbstractMultiplePendingRequestsRemoteService;
import com.android.internal.infra.AbstractRemoteService;

import java.util.concurrent.Executor;
import java.util.function.Consumer;

/**
 * Interface for communicating with the role controller.
 *
 * @hide
 */
@SystemService(Context.ROLE_CONTROLLER_SERVICE)
public class RoleControllerManager {

    private static final String LOG_TAG = RoleControllerManager.class.getSimpleName();

    private static volatile ComponentName sRemoteServiceComponentName;

    private static final Object sRemoteServicesLock = new Object();

    /**
     * Global remote services (per user) used by all {@link RoleControllerManager managers}.
     */
    @GuardedBy("sRemoteServicesLock")
    private static final SparseArray<RemoteService> sRemoteServices = new SparseArray<>();

    @NonNull
    private final RemoteService mRemoteService;

    /**
     * Initialize the remote service component name once so that we can avoid acquiring the
     * PackageManagerService lock in constructor.
     *
     * @see #createWithInitializedRemoteServiceComponentName(Handler, Context)
     */
    public static void initializeRemoteServiceComponentName(@NonNull Context context) {
        sRemoteServiceComponentName = getRemoteServiceComponentName(context);
    }

    /**
     * Create a {@link RoleControllerManager} instance with the initialized remote service component
     * name so that we can avoid acquiring the PackageManagerService lock in constructor.
     *
     * @see #initializeRemoteServiceComponentName(Context)
     */
    @NonNull
    public static RoleControllerManager createWithInitializedRemoteServiceComponentName(
            @NonNull Handler handler, @NonNull Context context) {
        return new RoleControllerManager(sRemoteServiceComponentName, handler, context);
    }

    private RoleControllerManager(@NonNull ComponentName remoteServiceComponentName,
            @NonNull Handler handler, @NonNull Context context) {
        synchronized (sRemoteServicesLock) {
            int userId = context.getUserId();
            RemoteService remoteService = sRemoteServices.get(userId);
            if (remoteService == null) {
                remoteService = new RemoteService(ActivityThread.currentApplication(),
                        remoteServiceComponentName, handler, userId);
                sRemoteServices.put(userId, remoteService);
            }
            mRemoteService = remoteService;
        }
    }

    public RoleControllerManager(@NonNull Context context) {
        this(getRemoteServiceComponentName(context), context.getMainThreadHandler(), context);
    }

    @NonNull
    private static ComponentName getRemoteServiceComponentName(@NonNull Context context) {
        Intent intent = new Intent(RoleControllerService.SERVICE_INTERFACE);
        PackageManager packageManager = context.getPackageManager();
        intent.setPackage(packageManager.getPermissionControllerPackageName());
        ResolveInfo resolveInfo = packageManager.resolveService(intent, 0);
        return resolveInfo.getComponentInfo().getComponentName();
    }

    /**
     * @see RoleControllerService#onGrantDefaultRoles()
     */
    public void grantDefaultRoles(@NonNull @CallbackExecutor Executor executor,
            @NonNull Consumer<Boolean> callback) {
        mRemoteService.scheduleRequest(new GrantDefaultRolesRequest(mRemoteService, executor,
                callback));
    }

    /**
     * @see RoleControllerService#onAddRoleHolder(String, String, int)
     */
    public void onAddRoleHolder(@NonNull String roleName, @NonNull String packageName,
            @RoleManager.ManageHoldersFlags int flags, @NonNull RemoteCallback callback) {
        mRemoteService.scheduleRequest(new OnAddRoleHolderRequest(mRemoteService, roleName,
                packageName, flags, callback));
    }

    /**
     * @see RoleControllerService#onRemoveRoleHolder(String, String, int)
     */
    public void onRemoveRoleHolder(@NonNull String roleName, @NonNull String packageName,
            @RoleManager.ManageHoldersFlags int flags, @NonNull RemoteCallback callback) {
        mRemoteService.scheduleRequest(new OnRemoveRoleHolderRequest(mRemoteService, roleName,
                packageName, flags, callback));
    }

    /**
     * @see RoleControllerService#onClearRoleHolders(String, int)
     */
    public void onClearRoleHolders(@NonNull String roleName,
            @RoleManager.ManageHoldersFlags int flags, @NonNull RemoteCallback callback) {
        mRemoteService.scheduleRequest(new OnClearRoleHoldersRequest(mRemoteService, roleName,
                flags, callback));
    }

    /**
     * @see RoleControllerService#onIsApplicationQualifiedForRole(String, String)
     */
    @RequiresPermission(Manifest.permission.MANAGE_ROLE_HOLDERS)
    public void isApplicationQualifiedForRole(@NonNull String roleName, @NonNull String packageName,
            @NonNull @CallbackExecutor Executor executor, @NonNull Consumer<Boolean> callback) {
        mRemoteService.scheduleRequest(new IsApplicationQualifiedForRoleRequest(mRemoteService,
                roleName, packageName, executor, callback));
    }

    /**
     * @see RoleControllerService#onIsRoleVisible(String)
     */
    @RequiresPermission(Manifest.permission.MANAGE_ROLE_HOLDERS)
    public void isRoleVisible(@NonNull String roleName,
            @NonNull @CallbackExecutor Executor executor, @NonNull Consumer<Boolean> callback) {
        mRemoteService.scheduleRequest(new IsRoleVisibleRequest(mRemoteService, roleName, executor,
                callback));
    }

    /**
     * Connection to the remote service.
     */
    private static final class RemoteService extends AbstractMultiplePendingRequestsRemoteService<
            RemoteService, IRoleController> {

        private static final long UNBIND_DELAY_MILLIS = 15 * 1000;
        private static final long REQUEST_TIMEOUT_MILLIS = 15 * 1000;

        /**
         * Create a connection to the remote service
         *
         * @param context the context to use
         * @param componentName the component of the service to connect to
         * @param handler the handler for binding service and callbacks
         * @param userId the user whom remote service should be connected as
         */
        RemoteService(@NonNull Context context, @NonNull ComponentName componentName,
                @NonNull Handler handler, @UserIdInt int userId) {
            super(context, RoleControllerService.SERVICE_INTERFACE, componentName, userId,
                    service -> Log.e(LOG_TAG, "RemoteService " + service + " died"), handler, 0,
                    false, 1);
        }

        /**
         * @return The default handler used by this service.
         */
        @NonNull
        public Handler getHandler() {
            return mHandler;
        }

        @Override
        protected @NonNull IRoleController getServiceInterface(@NonNull IBinder binder) {
            return IRoleController.Stub.asInterface(binder);
        }

        @Override
        protected long getTimeoutIdleBindMillis() {
            return UNBIND_DELAY_MILLIS;
        }

        @Override
        protected long getRemoteRequestMillis() {
            return REQUEST_TIMEOUT_MILLIS;
        }

        @Override
        public void scheduleRequest(
                @NonNull BasePendingRequest<RemoteService, IRoleController> pendingRequest) {
            super.scheduleRequest(pendingRequest);
        }

        @Override
        public void scheduleAsyncRequest(@NonNull AsyncRequest<IRoleController> request) {
            super.scheduleAsyncRequest(request);
        }
    }

    /**
     * Request for {@link #grantDefaultRoles(Executor, Consumer)}.
     */
    private static final class GrantDefaultRolesRequest
            extends AbstractRemoteService.PendingRequest<RemoteService, IRoleController> {

        @NonNull
        private final Executor mExecutor;
        @NonNull
        private final Consumer<Boolean> mCallback;

        @NonNull
        private final RemoteCallback mRemoteCallback;

        private GrantDefaultRolesRequest(@NonNull RemoteService service,
                @NonNull @CallbackExecutor Executor executor, @NonNull Consumer<Boolean> callback) {
            super(service);

            mExecutor = executor;
            mCallback = callback;

            mRemoteCallback = new RemoteCallback(result -> mExecutor.execute(() -> {
                long token = Binder.clearCallingIdentity();
                try {
                    boolean successful = result != null;
                    mCallback.accept(successful);
                } finally {
                    Binder.restoreCallingIdentity(token);
                    finish();
                }
            }));
        }

        @Override
        protected void onTimeout(@NonNull RemoteService remoteService) {
            mExecutor.execute(() -> mCallback.accept(false));
        }

        @Override
        public void run() {
            try {
                getService().getServiceInterface().grantDefaultRoles(mRemoteCallback);
            } catch (RemoteException e) {
                Log.e(LOG_TAG, "Error calling grantDefaultRoles()", e);
            }
        }

        @Override
        protected void onFailed() {
            mRemoteCallback.sendResult(null);
        }
    }

    /**
     * Request for {@link #onAddRoleHolder(String, String, int, RemoteCallback)}.
     */
    private static final class OnAddRoleHolderRequest
            extends AbstractRemoteService.PendingRequest<RemoteService, IRoleController> {

        @NonNull
        private final String mRoleName;
        @NonNull
        private final String mPackageName;
        @RoleManager.ManageHoldersFlags
        private final int mFlags;
        @NonNull
        private final RemoteCallback mCallback;

        @NonNull
        private final RemoteCallback mRemoteCallback;

        private OnAddRoleHolderRequest(@NonNull RemoteService service, @NonNull String roleName,
                @NonNull String packageName, @RoleManager.ManageHoldersFlags int flags,
                @NonNull RemoteCallback callback) {
            super(service);

            mRoleName = roleName;
            mPackageName = packageName;
            mFlags = flags;
            mCallback = callback;

            mRemoteCallback = new RemoteCallback(result -> {
                long token = Binder.clearCallingIdentity();
                try {
                    mCallback.sendResult(result);
                } finally {
                    Binder.restoreCallingIdentity(token);
                    finish();
                }
            });
        }

        @Override
        protected void onTimeout(@NonNull RemoteService remoteService) {
            mCallback.sendResult(null);
        }

        @Override
        public void run() {
            try {
                getService().getServiceInterface().onAddRoleHolder(mRoleName, mPackageName, mFlags,
                        mRemoteCallback);
            } catch (RemoteException e) {
                Log.e(LOG_TAG, "Error calling onAddRoleHolder()", e);
            }
        }
    }

    /**
     * Request for {@link #onRemoveRoleHolder(String, String, int, RemoteCallback)}.
     */
    private static final class OnRemoveRoleHolderRequest
            extends AbstractRemoteService.PendingRequest<RemoteService, IRoleController> {

        @NonNull
        private final String mRoleName;
        @NonNull
        private final String mPackageName;
        @RoleManager.ManageHoldersFlags
        private final int mFlags;
        @NonNull
        private final RemoteCallback mCallback;

        @NonNull
        private final RemoteCallback mRemoteCallback;

        private OnRemoveRoleHolderRequest(@NonNull RemoteService service, @NonNull String roleName,
                @NonNull String packageName, @RoleManager.ManageHoldersFlags int flags,
                @NonNull RemoteCallback callback) {
            super(service);

            mRoleName = roleName;
            mPackageName = packageName;
            mFlags = flags;
            mCallback = callback;

            mRemoteCallback = new RemoteCallback(result -> {
                long token = Binder.clearCallingIdentity();
                try {
                    mCallback.sendResult(result);
                } finally {
                    Binder.restoreCallingIdentity(token);
                    finish();
                }
            });
        }

        @Override
        protected void onTimeout(@NonNull RemoteService remoteService) {
            mCallback.sendResult(null);
        }

        @Override
        public void run() {
            try {
                getService().getServiceInterface().onRemoveRoleHolder(mRoleName, mPackageName,
                        mFlags, mRemoteCallback);
            } catch (RemoteException e) {
                Log.e(LOG_TAG, "Error calling onRemoveRoleHolder()", e);
            }
        }
    }

    /**
     * Request for {@link #onClearRoleHolders(String, int, RemoteCallback)}.
     */
    private static final class OnClearRoleHoldersRequest
            extends AbstractRemoteService.PendingRequest<RemoteService, IRoleController> {

        @NonNull
        private final String mRoleName;
        @RoleManager.ManageHoldersFlags
        private final int mFlags;
        @NonNull
        private final RemoteCallback mCallback;

        @NonNull
        private final RemoteCallback mRemoteCallback;

        private OnClearRoleHoldersRequest(@NonNull RemoteService service, @NonNull String roleName,
                @RoleManager.ManageHoldersFlags int flags, @NonNull RemoteCallback callback) {
            super(service);

            mRoleName = roleName;
            mFlags = flags;
            mCallback = callback;

            mRemoteCallback = new RemoteCallback(result -> {
                long token = Binder.clearCallingIdentity();
                try {
                    mCallback.sendResult(result);
                } finally {
                    Binder.restoreCallingIdentity(token);
                    finish();
                }
            });
        }

        @Override
        protected void onTimeout(@NonNull RemoteService remoteService) {
            mCallback.sendResult(null);
        }

        @Override
        public void run() {
            try {
                getService().getServiceInterface().onClearRoleHolders(mRoleName, mFlags,
                        mRemoteCallback);
            } catch (RemoteException e) {
                Log.e(LOG_TAG, "Error calling onClearRoleHolders()", e);
            }
        }
    }

    /**
     * Request for {@link #isApplicationQualifiedForRole(String, String, Executor, Consumer)}
     */
    private static final class IsApplicationQualifiedForRoleRequest extends
            AbstractRemoteService.PendingRequest<RemoteService, IRoleController> {

        @NonNull
        private final String mRoleName;
        @NonNull
        private final String mPackageName;
        @NonNull
        private final Executor mExecutor;
        @NonNull
        private final Consumer<Boolean> mCallback;

        @NonNull
        private final RemoteCallback mRemoteCallback;

        private IsApplicationQualifiedForRoleRequest(@NonNull RemoteService service,
                @NonNull String roleName, @NonNull String packageName,
                @CallbackExecutor @NonNull Executor executor, @NonNull Consumer<Boolean> callback) {
            super(service);

            mRoleName = roleName;
            mPackageName = packageName;
            mExecutor = executor;
            mCallback = callback;

            mRemoteCallback = new RemoteCallback(result -> mExecutor.execute(() -> {
                long token = Binder.clearCallingIdentity();
                try {
                    boolean qualified = result != null;
                    mCallback.accept(qualified);
                } finally {
                    Binder.restoreCallingIdentity(token);
                    finish();
                }
            }));
        }

        @Override
        protected void onTimeout(RemoteService remoteService) {
            mExecutor.execute(() -> mCallback.accept(false));
        }

        @Override
        public void run() {
            try {
                getService().getServiceInterface().isApplicationQualifiedForRole(mRoleName,
                        mPackageName, mRemoteCallback);
            } catch (RemoteException e) {
                Log.e(LOG_TAG, "Error calling isApplicationQualifiedForRole()", e);
            }
        }
    }

    /**
     * Request for {@link #isRoleVisible(String, Executor, Consumer)}
     */
    private static final class IsRoleVisibleRequest
            extends AbstractRemoteService.PendingRequest<RemoteService, IRoleController> {

        @NonNull
        private final String mRoleName;
        @NonNull
        private final Executor mExecutor;
        @NonNull
        private final Consumer<Boolean> mCallback;

        @NonNull
        private final RemoteCallback mRemoteCallback;

        private IsRoleVisibleRequest(@NonNull RemoteService service, @NonNull String roleName,
                @CallbackExecutor @NonNull Executor executor, @NonNull Consumer<Boolean> callback) {
            super(service);

            mRoleName = roleName;
            mExecutor = executor;
            mCallback = callback;

            mRemoteCallback = new RemoteCallback(result -> mExecutor.execute(() -> {
                long token = Binder.clearCallingIdentity();
                try {
                    boolean visible = result != null;
                    mCallback.accept(visible);
                } finally {
                    Binder.restoreCallingIdentity(token);
                    finish();
                }
            }));
        }

        @Override
        protected void onTimeout(RemoteService remoteService) {
            mExecutor.execute(() -> mCallback.accept(false));
        }

        @Override
        public void run() {
            try {
                getService().getServiceInterface().isRoleVisible(mRoleName, mRemoteCallback);
            } catch (RemoteException e) {
                Log.e(LOG_TAG, "Error calling isRoleVisible()", e);
            }
        }
    }
}
