// Copyright (C) 2012 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.google.gerrit.server.account;

import com.google.common.base.Predicate;
import com.google.common.collect.Sets;
import com.google.gerrit.common.data.PermissionRule;
import com.google.gerrit.common.errors.NoSuchGroupException;
import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.reviewdb.client.AccountGroup;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.git.AccountsSection;
import com.google.gerrit.server.group.SystemGroupBackend;
import com.google.gerrit.server.project.ProjectCache;
import com.google.inject.Inject;
import com.google.inject.Provider;

import java.util.HashSet;
import java.util.Set;

/** Access control management for one account's access to other accounts. */
public class AccountControl {
  public static class Factory {
    private final ProjectCache projectCache;
    private final GroupControl.Factory groupControlFactory;
    private final Provider<CurrentUser> user;
    private final IdentifiedUser.GenericFactory userFactory;
    private final AccountVisibility accountVisibility;

    @Inject
    Factory(final ProjectCache projectCache,
        final GroupControl.Factory groupControlFactory,
        final Provider<CurrentUser> user,
        final IdentifiedUser.GenericFactory userFactory,
        final AccountVisibility accountVisibility) {
      this.projectCache = projectCache;
      this.groupControlFactory = groupControlFactory;
      this.user = user;
      this.userFactory = userFactory;
      this.accountVisibility = accountVisibility;
    }

    public AccountControl get() {
      return new AccountControl(projectCache, groupControlFactory, user.get(),
          userFactory, accountVisibility);
    }
  }

  private final AccountsSection accountsSection;
  private final GroupControl.Factory groupControlFactory;
  private final CurrentUser currentUser;
  private final IdentifiedUser.GenericFactory userFactory;
  private final AccountVisibility accountVisibility;

  AccountControl(final ProjectCache projectCache,
        final GroupControl.Factory groupControlFactory,
        final CurrentUser currentUser,
        final IdentifiedUser.GenericFactory userFactory,
        final AccountVisibility accountVisibility) {
    this.accountsSection =
        projectCache.getAllProjects().getConfig().getAccountsSection();
    this.groupControlFactory = groupControlFactory;
    this.currentUser = currentUser;
    this.userFactory = userFactory;
    this.accountVisibility = accountVisibility;
  }

  /**
   * Returns true if the otherUser is allowed to see the current user, based
   * on the account visibility policy. Depending on the group membership
   * realms supported, this may not be able to determine SAME_GROUP or
   * VISIBLE_GROUP correctly (defaulting to not being visible). This is because
   * {@link GroupMembership#getKnownGroups()} may only return a subset of the
   * effective groups.
   */
  public boolean canSee(final Account otherUser) {
    return canSee(otherUser.getId());
  }

  /**
   * Returns true if the otherUser is allowed to see the current user, based
   * on the account visibility policy. Depending on the group membership
   * realms supported, this may not be able to determine SAME_GROUP or
   * VISIBLE_GROUP correctly (defaulting to not being visible). This is because
   * {@link GroupMembership#getKnownGroups()} may only return a subset of the
   * effective groups.
   */
  public boolean canSee(final Account.Id otherUser) {
    // Special case: I can always see myself.
    if (currentUser.isIdentifiedUser()
        && ((IdentifiedUser) currentUser).getAccountId().equals(otherUser)) {
      return true;
    }
    if (currentUser.getCapabilities().canViewAllAccounts()) {
      return true;
    }

    switch (accountVisibility) {
      case ALL:
        return true;
      case SAME_GROUP: {
        Set<AccountGroup.UUID> usersGroups = groupsOf(otherUser);
        for (PermissionRule rule : accountsSection.getSameGroupVisibility()) {
          if (rule.isBlock() || rule.isDeny()) {
            usersGroups.remove(rule.getGroup().getUUID());
          }
        }

        if (currentUser.getEffectiveGroups().containsAnyOf(usersGroups)) {
          return true;
        }
        break;
      }
      case VISIBLE_GROUP: {
        Set<AccountGroup.UUID> usersGroups = groupsOf(otherUser);
        for (AccountGroup.UUID usersGroup : usersGroups) {
          try {
            if (groupControlFactory.controlFor(usersGroup).isVisible()) {
              return true;
            }
          } catch (NoSuchGroupException e) {
            continue;
          }
        }
        break;
      }
      case NONE:
        break;
      default:
        throw new IllegalStateException("Bad AccountVisibility " + accountVisibility);
    }
    return false;
  }

  private Set<AccountGroup.UUID> groupsOf(Account.Id account) {
    return new HashSet<>(Sets.filter(
      userFactory.create(account).getEffectiveGroups().getKnownGroups(),
      new Predicate<AccountGroup.UUID>() {
        @Override
        public boolean apply(AccountGroup.UUID in) {
          return !SystemGroupBackend.isSystemGroup(in);
        }
      }));
  }
}
