/*
 * 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.tools.lint.checks;

import com.android.annotations.NonNull;
import com.android.annotations.Nullable;
import com.android.sdklib.AndroidVersion;
import com.google.common.annotations.VisibleForTesting;
import java.util.Collections;
import java.util.Set;

/**
 * A {@linkplain PermissionHolder} knows which permissions are held/granted and can look up
 * individual permissions and respond to queries about whether they are held or not.
 */
public interface PermissionHolder {

    /** Returns true if the permission holder has been granted the given permission */
    boolean hasPermission(@NonNull String permission);

    /** Returns true if the given permission is known to be revocable for targetSdkVersion &ge; M */
    boolean isRevocable(@NonNull String permission);

    @NonNull
    AndroidVersion getMinSdkVersion();

    @NonNull
    AndroidVersion getTargetSdkVersion();

    /** A convenience implementation of {@link PermissionHolder} backed by a set */
    class SetPermissionLookup implements PermissionHolder {
        private final Set<String> mGrantedPermissions;
        private final Set<String> mRevocablePermissions;
        private final AndroidVersion mMinSdkVersion;
        private final AndroidVersion mTargetSdkVersion;

        public SetPermissionLookup(
                @NonNull Set<String> grantedPermissions,
                @NonNull Set<String> revocablePermissions,
                @NonNull AndroidVersion minSdkVersion,
                @NonNull AndroidVersion targetSdkVersion) {
            mGrantedPermissions = grantedPermissions;
            mRevocablePermissions = revocablePermissions;
            mMinSdkVersion = minSdkVersion;
            mTargetSdkVersion = targetSdkVersion;
        }

        @VisibleForTesting
        public SetPermissionLookup(
                @NonNull Set<String> grantedPermissions,
                @NonNull Set<String> revocablePermissions) {
            this(
                    grantedPermissions,
                    revocablePermissions,
                    AndroidVersion.DEFAULT,
                    AndroidVersion.DEFAULT);
        }

        @VisibleForTesting
        public SetPermissionLookup(@NonNull Set<String> grantedPermissions) {
            this(grantedPermissions, Collections.emptySet());
        }

        @Override
        public boolean hasPermission(@NonNull String permission) {
            return mGrantedPermissions.contains(permission);
        }

        @Override
        public boolean isRevocable(@NonNull String permission) {
            return mRevocablePermissions.contains(permission);
        }

        @NonNull
        @Override
        public AndroidVersion getMinSdkVersion() {
            return mMinSdkVersion;
        }

        @NonNull
        @Override
        public AndroidVersion getTargetSdkVersion() {
            return mTargetSdkVersion;
        }

        /**
         * Creates a {@linkplain PermissionHolder} which combines the permissions held by the given
         * holder, with the permissions implied by the given {@link PermissionRequirement}
         */
        @NonNull
        public static PermissionHolder join(
                @NonNull PermissionHolder lookup, @NonNull PermissionRequirement requirement) {
            SetPermissionLookup empty =
                    new SetPermissionLookup(
                            Collections.emptySet(),
                            Collections.emptySet(),
                            lookup.getMinSdkVersion(),
                            lookup.getTargetSdkVersion());
            return join(lookup, requirement.getMissingPermissions(empty));
        }

        /**
         * Creates a {@linkplain PermissionHolder} which combines the permissions held by the given
         * holder, along with a set of additional permission names
         */
        @NonNull
        public static PermissionHolder join(
                @NonNull final PermissionHolder lookup, @Nullable final Set<String> permissions) {
            if (permissions != null && !permissions.isEmpty()) {
                return new PermissionHolder() {
                    @Override
                    public boolean hasPermission(@NonNull String permission) {
                        return lookup.hasPermission(permission) || permissions.contains(permission);
                    }

                    @Override
                    public boolean isRevocable(@NonNull String permission) {
                        return lookup.isRevocable(permission);
                    }

                    @NonNull
                    @Override
                    public AndroidVersion getMinSdkVersion() {
                        return lookup.getMinSdkVersion();
                    }

                    @NonNull
                    @Override
                    public AndroidVersion getTargetSdkVersion() {
                        return lookup.getTargetSdkVersion();
                    }
                };
            }
            return lookup;
        }
    }
}
