/*
 * 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.nene.users;

import static android.Manifest.permission.CREATE_USERS;
import static android.Manifest.permission.INTERACT_ACROSS_USERS;
import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
import static android.os.Build.VERSION.SDK_INT;
import static android.os.Build.VERSION_CODES.S;
import static android.os.Build.VERSION_CODES.S_V2;
import static android.os.Process.myUserHandle;

import static com.android.bedstead.nene.users.UserType.MANAGED_PROFILE_TYPE_NAME;
import static com.android.bedstead.nene.users.UserType.SECONDARY_USER_TYPE_NAME;
import static com.android.bedstead.nene.users.UserType.SYSTEM_USER_TYPE_NAME;

import android.app.ActivityManager;
import android.content.Context;
import android.content.pm.UserInfo;
import android.os.Build;
import android.os.UserHandle;
import android.os.UserManager;

import androidx.annotation.CheckResult;
import androidx.annotation.Nullable;

import com.android.bedstead.nene.TestApis;
import com.android.bedstead.nene.exceptions.AdbException;
import com.android.bedstead.nene.exceptions.AdbParseException;
import com.android.bedstead.nene.exceptions.NeneException;
import com.android.bedstead.nene.permissions.PermissionContext;
import com.android.bedstead.nene.permissions.Permissions;
import com.android.bedstead.nene.utils.Poll;
import com.android.bedstead.nene.utils.ShellCommand;
import com.android.bedstead.nene.utils.Versions;

import java.time.Duration;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public final class Users {

    static final int SYSTEM_USER_ID = 0;
    private static final Duration WAIT_FOR_USER_TIMEOUT = Duration.ofMinutes(4);

    private Map<Integer, AdbUser> mCachedUsers = null;
    private Map<String, UserType> mCachedUserTypes = null;
    private Set<UserType> mCachedUserTypeValues = null;
    private final AdbUserParser mParser;
    private static final UserManager sUserManager =
            TestApis.context().instrumentedContext().getSystemService(UserManager.class);
    private Map<Integer, UserReference> mUsers = new ConcurrentHashMap<>();

    public static final Users sInstance = new Users();

    private Users() {
        mParser = AdbUserParser.get(SDK_INT);
    }

    /** Get all {@link UserReference}s on the device. */
    public Collection<UserReference> all() {
        if (!Versions.meetsMinimumSdkVersionRequirement(S)) {
            fillCache();
            return mCachedUsers.keySet().stream().map(UserReference::new)
                    .collect(Collectors.toSet());
        }

        return users().map(
                ui -> find(ui.id)
        ).collect(Collectors.toSet());
    }

    /**
     * Gets a {@link UserReference} for the initial user for the device.
     *
     * <p>This will be the {@link #system()} user on most systems.</p>
     */
    public UserReference initial() {
        if (!isHeadlessSystemUserMode()) {
            return system();
        }
        if (TestApis.packages().features().contains("android.hardware.type.automotive")) {
            try {
                return ShellCommand.builder("cmd car_service get-initial-user")
                        .executeAndParseOutput(i -> find(Integer.parseInt(i.trim())));
            } catch (AdbException e) {
                throw new NeneException("Error finding initial user on Auto", e);
            }
        }

        List<UserReference> users = new ArrayList<>(all());
        users.sort(Comparator.comparingInt(UserReference::id));

        for (UserReference user : users) {
            if (user.parent() == null) {
                return user;
            }
        }

        throw new NeneException("No initial user available");
    }

    /** Get a {@link UserReference} for the user currently switched to. */
    public UserReference current() {
        if (Versions.meetsMinimumSdkVersionRequirement(S)) {
            try (PermissionContext p =
                         TestApis.permissions().withPermission(INTERACT_ACROSS_USERS_FULL)) {
                return find(ActivityManager.getCurrentUser());
            }
        }

        try {
            return find((int) ShellCommand.builder("am get-current-user")
                    .executeAndParseOutput(i -> Integer.parseInt(i.trim())));
        } catch (AdbException e) {
            throw new NeneException("Error getting current user", e);
        }
    }

    /** Get a {@link UserReference} for the user running the current test process. */
    public UserReference instrumented() {
        return find(myUserHandle());
    }

    /** Get a {@link UserReference} for the system user. */
    public UserReference system() {
        return find(0);
    }

    /** Get a {@link UserReference} by {@code id}. */
    public UserReference find(int id) {
        if (!mUsers.containsKey(id)) {
            mUsers.put(id, new UserReference(id));
        }
        return mUsers.get(id);
    }

    /** Get a {@link UserReference} by {@code userHandle}. */
    public UserReference find(UserHandle userHandle) {
        return find(userHandle.getIdentifier());
    }

    /** Get all supported {@link UserType}s. */
    public Set<UserType> supportedTypes() {
        // TODO(b/203557600): Stop using adb
        ensureSupportedTypesCacheFilled();
        return mCachedUserTypeValues;
    }

    /** Get a {@link UserType} with the given {@code typeName}, or {@code null} */
    @Nullable
    public UserType supportedType(String typeName) {
        ensureSupportedTypesCacheFilled();
        return mCachedUserTypes.get(typeName);
    }

    /**
     * Find all users which have the given {@link UserType}.
     */
    public Set<UserReference> findUsersOfType(UserType userType) {
        if (userType == null) {
            throw new NullPointerException();
        }

        if (userType.baseType().contains(UserType.BaseType.PROFILE)) {
            throw new NeneException("Cannot use findUsersOfType with profile type " + userType);
        }

        return all().stream()
                .filter(u -> u.type().equals(userType))
                .collect(Collectors.toSet());
    }

    /**
     * Find a single user which has the given {@link UserType}.
     *
     * <p>If there are no users of the given type, {@code Null} will be returned.
     *
     * <p>If there is more than one user of the given type, {@link NeneException} will be thrown.
     */
    @Nullable
    public UserReference findUserOfType(UserType userType) {
        Set<UserReference> users = findUsersOfType(userType);

        if (users.isEmpty()) {
            return null;
        } else if (users.size() > 1) {
            throw new NeneException("findUserOfType called but there is more than 1 user of type "
                    + userType + ". Found: " + users);
        }

        return users.iterator().next();
    }

    /**
     * Find all users which have the given {@link UserType} and the given parent.
     */
    public Set<UserReference> findProfilesOfType(UserType userType, UserReference parent) {
        if (userType == null || parent == null) {
            throw new NullPointerException();
        }

        if (!userType.baseType().contains(UserType.BaseType.PROFILE)) {
            throw new NeneException("Cannot use findProfilesOfType with non-profile type "
                    + userType);
        }

        return all().stream()
                .filter(u -> parent.equals(u.parent())
                        && u.type().equals(userType))
                .collect(Collectors.toSet());
    }

    /**
     * Find all users which have the given {@link UserType} and the given parent.
     *
     * <p>If there are no users of the given type and parent, {@code Null} will be returned.
     *
     * <p>If there is more than one user of the given type and parent, {@link NeneException} will
     * be thrown.
     */
    @Nullable
    public UserReference findProfileOfType(UserType userType, UserReference parent) {
        Set<UserReference> profiles = findProfilesOfType(userType, parent);

        if (profiles.isEmpty()) {
            return null;
        } else if (profiles.size() > 1) {
            throw new NeneException("findProfileOfType called but there is more than 1 user of "
                    + "type " + userType + " with parent " + parent + ". Found: " + profiles);
        }

        return profiles.iterator().next();
    }

    private void ensureSupportedTypesCacheFilled() {
        if (mCachedUserTypes != null) {
            // SupportedTypes don't change so don't need to be refreshed
            return;
        }
        if (SDK_INT < Build.VERSION_CODES.R) {
            mCachedUserTypes = new HashMap<>();
            mCachedUserTypes.put(MANAGED_PROFILE_TYPE_NAME, managedProfileUserType());
            mCachedUserTypes.put(SYSTEM_USER_TYPE_NAME, systemUserType());
            mCachedUserTypes.put(SECONDARY_USER_TYPE_NAME, secondaryUserType());
            mCachedUserTypeValues = new HashSet<>();
            mCachedUserTypeValues.addAll(mCachedUserTypes.values());
            return;
        }

        fillCache();
    }

    private UserType managedProfileUserType() {
        UserType.MutableUserType managedProfileMutableUserType = new UserType.MutableUserType();
        managedProfileMutableUserType.mName = MANAGED_PROFILE_TYPE_NAME;
        managedProfileMutableUserType.mBaseType = Set.of(UserType.BaseType.PROFILE);
        managedProfileMutableUserType.mEnabled = true;
        managedProfileMutableUserType.mMaxAllowed = -1;
        managedProfileMutableUserType.mMaxAllowedPerParent = 1;
        return new UserType(managedProfileMutableUserType);
    }

    private UserType systemUserType() {
        UserType.MutableUserType managedProfileMutableUserType = new UserType.MutableUserType();
        managedProfileMutableUserType.mName = SYSTEM_USER_TYPE_NAME;
        managedProfileMutableUserType.mBaseType =
                Set.of(UserType.BaseType.FULL, UserType.BaseType.SYSTEM);
        managedProfileMutableUserType.mEnabled = true;
        managedProfileMutableUserType.mMaxAllowed = -1;
        managedProfileMutableUserType.mMaxAllowedPerParent = -1;
        return new UserType(managedProfileMutableUserType);
    }

    private UserType secondaryUserType() {
        UserType.MutableUserType managedProfileMutableUserType = new UserType.MutableUserType();
        managedProfileMutableUserType.mName = SECONDARY_USER_TYPE_NAME;
        managedProfileMutableUserType.mBaseType = Set.of(UserType.BaseType.FULL);
        managedProfileMutableUserType.mEnabled = true;
        managedProfileMutableUserType.mMaxAllowed = -1;
        managedProfileMutableUserType.mMaxAllowedPerParent = -1;
        return new UserType(managedProfileMutableUserType);
    }

    /**
     * Create a new user.
     */
    @CheckResult
    public UserBuilder createUser() {
        return new UserBuilder();
    }

    /**
     * Get a {@link UserReference} to a user who does not exist.
     */
    public UserReference nonExisting() {
        Set<Integer> userIds;
        if (Versions.meetsMinimumSdkVersionRequirement(S)) {
            userIds = users().map(ui -> ui.id).collect(Collectors.toSet());
        } else {
            fillCache();
            userIds = mCachedUsers.keySet();
        }

        int id = 0;

        while (userIds.contains(id)) {
            id++;
        }

        return find(id);
    }

    private void fillCache() {
        try {
            // TODO: Replace use of adb on supported versions of Android
            String userDumpsysOutput = ShellCommand.builder("dumpsys user").execute();
            AdbUserParser.ParseResult result = mParser.parse(userDumpsysOutput);

            mCachedUsers = result.mUsers;
            if (result.mUserTypes != null) {
                mCachedUserTypes = result.mUserTypes;
            } else {
                ensureSupportedTypesCacheFilled();
            }

            Iterator<Map.Entry<Integer, AdbUser>> iterator = mCachedUsers.entrySet().iterator();

            while (iterator.hasNext()) {
                Map.Entry<Integer, AdbUser> entry = iterator.next();

                if (entry.getValue().isRemoving()) {
                    // We don't expose users who are currently being removed
                    iterator.remove();
                    continue;
                }

                AdbUser.MutableUser mutableUser = entry.getValue().mMutableUser;

                if (SDK_INT < Build.VERSION_CODES.R) {
                    if (entry.getValue().id() == SYSTEM_USER_ID) {
                        mutableUser.mType = supportedType(SYSTEM_USER_TYPE_NAME);
                        mutableUser.mIsPrimary = true;
                    } else if (entry.getValue().hasFlag(AdbUser.FLAG_MANAGED_PROFILE)) {
                        mutableUser.mType =
                                supportedType(MANAGED_PROFILE_TYPE_NAME);
                        mutableUser.mIsPrimary = false;
                    } else {
                        mutableUser.mType =
                                supportedType(SECONDARY_USER_TYPE_NAME);
                        mutableUser.mIsPrimary = false;
                    }
                }

                if (SDK_INT < S) {
                    if (mutableUser.mType.baseType()
                            .contains(UserType.BaseType.PROFILE)) {
                        // We assume that all profiles before S were on the System User
                        mutableUser.mParent = find(SYSTEM_USER_ID);
                    }
                }
            }

            mCachedUserTypeValues = new HashSet<>();
            mCachedUserTypeValues.addAll(mCachedUserTypes.values());

        } catch (AdbException | AdbParseException e) {
            throw new RuntimeException("Error filling cache", e);
        }
    }

    /**
     * Block until the user with the given {@code userReference} to not exist or to be in the
     * correct state.
     *
     * <p>If this cannot be met before a timeout, a {@link NeneException} will be thrown.
     */
    @Nullable
    UserReference waitForUserToNotExistOrMatch(
            UserReference userReference, Function<UserReference, Boolean> userChecker) {
        return waitForUserToMatch(userReference, userChecker, /* waitForExist= */ false);
    }

    @Nullable
    private UserReference waitForUserToMatch(
            UserReference userReference, Function<UserReference, Boolean> userChecker,
            boolean waitForExist) {
        // TODO(scottjonathan): This is pretty heavy because we resolve everything when we know we
        //  are throwing away everything except one user. Optimise
        try {
            return Poll.forValue("user", () -> userReference)
                    .toMeet((user) -> {
                        if (user == null) {
                            return !waitForExist;
                        }
                        return userChecker.apply(user);
                    }).timeout(WAIT_FOR_USER_TIMEOUT)
                    .errorOnFail("Expected user to meet requirement")
                    .await();
        } catch (AssertionError e) {
            if (!userReference.exists()) {
                throw new NeneException(
                        "Timed out waiting for user state for user "
                                + userReference + ". User does not exist.", e);
            }
            throw new NeneException(
                    "Timed out waiting for user state, current state " + userReference, e
            );
        }
    }

    /** See {@link UserManager#isHeadlessSystemUserMode()}. */
    @SuppressWarnings("NewApi")
    public boolean isHeadlessSystemUserMode() {
        if (Versions.meetsMinimumSdkVersionRequirement(S)) {
            return UserManager.isHeadlessSystemUserMode();
        }

        return false;
    }

    /**
     * Set the stopBgUsersOnSwitch property.
     *
     * <p>This affects if background users will be swapped when switched away from on some devices.
     */
    public void setStopBgUsersOnSwitch(int value) {
        if (!Versions.meetsMinimumSdkVersionRequirement(S_V2)) {
            return;
        }
        Context context = TestApis.context().instrumentedContext();
        try (PermissionContext p = TestApis.permissions()
                .withPermission(INTERACT_ACROSS_USERS)) {
            context.getSystemService(ActivityManager.class).setStopUserOnSwitch(value);
        }
    }

    @Nullable
    AdbUser fetchUser(int id) {
        fillCache();
        return mCachedUsers.get(id);
    }

    static Stream<UserInfo> users() {
        if (Permissions.sIgnorePermissions.get()) {
            return sUserManager.getUsers(
                    /* excludePartial= */ false,
                    /* excludeDying= */ true,
                    /* excludePreCreated= */ false).stream();
        }

        try (PermissionContext p = TestApis.permissions().withPermission(CREATE_USERS)) {
            return sUserManager.getUsers(
                    /* excludePartial= */ false,
                    /* excludeDying= */ true,
                    /* excludePreCreated= */ false).stream();
        }
    }
}
