// Copyright (C) 2018 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.googlesource.gerrit.plugins.reviewers;

import static java.util.stream.Collectors.toSet;

import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.Sets;
import com.google.common.flogger.FluentLogger;
import com.google.gerrit.common.Nullable;
import com.google.gerrit.exceptions.StorageException;
import com.google.gerrit.extensions.common.AccountInfo;
import com.google.gerrit.extensions.restapi.UnprocessableEntityException;
import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.server.account.AccountResolver;
import com.google.gerrit.server.account.GroupMembers;
import com.google.gerrit.server.group.GroupResolver;
import com.google.gerrit.server.project.NoSuchProjectException;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.Singleton;
import java.io.IOException;
import java.util.Set;
import org.eclipse.jgit.errors.ConfigInvalidException;

/* Resolve account and group names to account ids */
@Singleton
class ReviewersResolver {
  private static final FluentLogger logger = FluentLogger.forEnclosingClass();

  private final AccountResolver accountResolver;
  private final Provider<GroupResolver> groupResolver;
  private final GroupMembers groupMembers;

  @Inject
  ReviewersResolver(
      AccountResolver accountResolver,
      Provider<GroupResolver> groupResolver,
      GroupMembers groupMembers) {
    this.accountResolver = accountResolver;
    this.groupResolver = groupResolver;
    this.groupMembers = groupMembers;
  }

  /**
   * Resolve a set of account names to {@link com.google.gerrit.reviewdb.client.Account.Id}s. Group
   * names are resolved to their account members.
   *
   * @param names the set of account names to convert
   * @param project the project name
   * @param changeNumber the change Id
   * @param uploader account to use to look up groups, or null if groups are not needed
   * @return set of {@link com.google.gerrit.reviewdb.client.Account.Id}s.
   */
  @VisibleForTesting
  Set<Account.Id> resolve(
      Set<String> names,
      Project.NameKey project,
      int changeNumber,
      @Nullable AccountInfo uploader) {
    Set<Account.Id> reviewers = Sets.newHashSetWithExpectedSize(names.size());
    for (String name : names) {
      if (resolveAccount(project, changeNumber, uploader, reviewers, name)) {
        continue;
      }

      resolveGroup(project, changeNumber, reviewers, groupMembers, name);
    }
    return reviewers;
  }

  private boolean resolveAccount(
      Project.NameKey project,
      int changeNumber,
      @Nullable AccountInfo uploader,
      Set<Account.Id> reviewers,
      String accountName) {
    try {
      AccountResolver.Result result = accountResolver.resolve(accountName);
      if (result.asList().size() == 1) {
        Account.Id id = result.asList().get(0).getAccount().getId();
        if (uploader == null || id.get() != uploader._accountId) {
          reviewers.add(id);
          return true;
        }
      }
      return false;
    } catch (StorageException | IOException | ConfigInvalidException e) {
      logger.atSevere().withCause(e).log(
          "For the change %d of project %s: failed to resolve account %s.",
          changeNumber, project, accountName);
      return true;
    }
  }

  private void resolveGroup(
      Project.NameKey project,
      int changeNumber,
      Set<Account.Id> reviewers,
      GroupMembers groupMembers,
      String group) {
    try {
      Set<Account.Id> accounts =
          groupMembers.listAccounts(groupResolver.get().parse(group).getGroupUUID(), project)
              .stream()
              .filter(Account::isActive)
              .map(Account::getId)
              .collect(toSet());
      reviewers.addAll(accounts);
    } catch (UnprocessableEntityException e) {
      logger.atWarning().log(
          "For the change %d of project %s: reviewer %s is neither an account nor a group.",
          changeNumber, project, group);
    } catch (NoSuchProjectException | IOException e) {
      logger.atSevere().withCause(e).log(
          "For the change %d of project %s: failed to list accounts for group %s.",
          changeNumber, project, group);
    }
  }
}
