/*
 * Copyright (C) 2022 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;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.os.IBinder;

import com.android.internal.util.Preconditions;

import java.util.List;

/**
 * Privileges granted to a Process that allows it to execute starts from the background.
 * @hide
 */
public class BackgroundStartPrivileges {
    /** No privileges. */
    public static final BackgroundStartPrivileges NONE = new BackgroundStartPrivileges(
            false, false, null);
    /** Allow activity starts (and implies allowing foreground service starts).  */
    public static final BackgroundStartPrivileges ALLOW_BAL = new BackgroundStartPrivileges(
            true, true, null);
    /** Allow foreground service starts. */
    public static final BackgroundStartPrivileges ALLOW_FGS = new BackgroundStartPrivileges(
            false, true, null);

    private final boolean mAllowsBackgroundActivityStarts;
    private final boolean mAllowsBackgroundForegroundServiceStarts;
    private final IBinder mOriginatingToken;

    private BackgroundStartPrivileges(boolean allowsBackgroundActivityStarts,
            boolean allowsBackgroundForegroundServiceStarts, @Nullable IBinder originatingToken) {
        Preconditions.checkArgument(
                !allowsBackgroundActivityStarts || allowsBackgroundForegroundServiceStarts,
                "backgroundActivityStarts implies bgFgServiceStarts");
        mAllowsBackgroundActivityStarts = allowsBackgroundActivityStarts;
        mAllowsBackgroundForegroundServiceStarts = allowsBackgroundForegroundServiceStarts;
        mOriginatingToken = originatingToken;
    }

    /**
     * Return a token that allows background activity starts and attributes it to a specific
     * originatingToken.
     */
    public static BackgroundStartPrivileges allowBackgroundActivityStarts(
            @Nullable IBinder originatingToken) {
        if (originatingToken == null) {
            // try to avoid creating new instances
            return ALLOW_BAL;
        }
        return new BackgroundStartPrivileges(true, true, originatingToken);
    }

    /**
     * Merge this {@link BackgroundStartPrivileges} with another {@link BackgroundStartPrivileges}.
     *
     * The resulting object will grant the union of the privileges of the merged objects.
     * The originating tokens is retained only if both {@link BackgroundStartPrivileges} are the
     * same.
     *
     * If one of the merged objects is {@link #NONE} then the other object is returned and the
     * originating token is NOT cleared.
     */
    public @NonNull BackgroundStartPrivileges merge(@Nullable BackgroundStartPrivileges other) {
        // shortcuts in case
        if (other == NONE || other == null) {
            return this;
        }
        if (this == NONE) {
            return other;
        }

        boolean allowsBackgroundActivityStarts =
                this.allowsBackgroundActivityStarts() || other.allowsBackgroundActivityStarts();
        boolean allowsBackgroundFgsStarts =
                this.allowsBackgroundFgsStarts() || other.allowsBackgroundFgsStarts();
        if (this.mOriginatingToken == other.mOriginatingToken) {
            // can reuse this?
            if (this.mAllowsBackgroundActivityStarts == allowsBackgroundActivityStarts
                    && this.mAllowsBackgroundForegroundServiceStarts == allowsBackgroundFgsStarts) {
                return this;
            }
            // can reuse other?
            if (other.mAllowsBackgroundActivityStarts == allowsBackgroundActivityStarts
                   && other.mAllowsBackgroundForegroundServiceStarts == allowsBackgroundFgsStarts) {
                return other;
            }
            // need to create a new instance (this should never happen)
            return new BackgroundStartPrivileges(allowsBackgroundActivityStarts,
                    allowsBackgroundFgsStarts, this.mOriginatingToken);
        } else {
            // no originating token -> can use standard instance
            if (allowsBackgroundActivityStarts) {
                return ALLOW_BAL;
            } else if (allowsBackgroundFgsStarts) {
                return ALLOW_FGS;
            } else {
                return NONE;
            }
        }
    }

    /**
     * Merge a collection of {@link BackgroundStartPrivileges} into a single token.
     *
     * The resulting object will grant the union of the privileges of the merged objects.
     * The originating tokens is retained only if all {@link BackgroundStartPrivileges} are the
     * same.
     *
     * If the list contains {@link #NONE}s these are ignored.
     */
    public static @NonNull BackgroundStartPrivileges merge(
            @Nullable List<BackgroundStartPrivileges> list) {
        if (list == null || list.isEmpty()) {
            return NONE;
        }
        BackgroundStartPrivileges current = list.get(0);
        for (int i = list.size(); i-- > 1; ) {
            current = current.merge(list.get(i));
        }
        return current;
    }

    /**
     * @return {@code true} if this grants the permission to start background activities from the
     * background.
     */
    public boolean allowsBackgroundActivityStarts() {
        return mAllowsBackgroundActivityStarts;
    }

    /**
     * @return {@code true} this grants the permission to start foreground services from the
     * background. */
    public boolean allowsBackgroundFgsStarts() {
        return mAllowsBackgroundForegroundServiceStarts;
    }

    /** @return true if this grants any privileges. */
    public boolean allowsAny() {
        return mAllowsBackgroundActivityStarts || mAllowsBackgroundForegroundServiceStarts;
    }

    /** Return true if this grants no privileges. */
    public boolean allowsNothing() {
        return !allowsAny();
    }

    /**
     * Gets the originating token.
     *
     * The originating token is optional information that allows to trace back the origin of this
     * object. Besides debugging, this is used to e.g. identify privileges created by the
     * notification service.
     */
    public @Nullable IBinder getOriginatingToken() {
        return mOriginatingToken;
    }

    @Override
    public String toString() {
        if (this == ALLOW_BAL) {
            return "BSP.ALLOW_BAL";
        }
        if (this == ALLOW_FGS) {
            return "BSP.ALLOW_FGS";
        }
        if (this == NONE) {
            return "BSP.NONE";
        }
        return "BackgroundStartPrivileges["
                + "allowsBackgroundActivityStarts=" + mAllowsBackgroundActivityStarts
                + ", allowsBackgroundForegroundServiceStarts="
                + mAllowsBackgroundForegroundServiceStarts
                + ", originatingToken=" + mOriginatingToken
                + ']';
    }
}
