// 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 user;
  private final IdentifiedUser.GenericFactory userFactory;
  private final AccountVisibility accountVisibility;

  AccountControl(final ProjectCache projectCache,
        final GroupControl.Factory groupControlFactory,
        final CurrentUser user,
        final IdentifiedUser.GenericFactory userFactory,
        final AccountVisibility accountVisibility) {
    this.accountsSection =
        projectCache.getAllProjects().getConfig().getAccountsSection();
    this.groupControlFactory = groupControlFactory;
    this.user = user;
    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 (user.isIdentifiedUser() && user.getAccountId().equals(otherUser)) {
      return true;
    }
    if (user.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 (user.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);
        }
      }));
  }
}
