// 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.server;

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

import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.Sets;
import com.google.gerrit.common.Nullable;
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.gwtorm.server.OrmException;
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;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/* Resolve account and group names to account ids */
@Singleton
class ReviewersResolver {
  private static final Logger log = LoggerFactory.getLogger(ReviewersResolver.class);

  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,
      AccountInfo uploader,
      Set<Account.Id> reviewers,
      String accountName) {
    try {
      Account account = accountResolver.find(accountName);
      if (account != null) {
        if (account.isActive()) {
          if (uploader == null || uploader._accountId != account.getId().get()) {
            reviewers.add(account.getId());
          }
          return true;
        }
        log.warn(
            "For the change {} of project {}: account {} is inactive.",
            changeNumber,
            project,
            accountName);
      }
    } catch (OrmException | IOException | ConfigInvalidException e) {
      // If the account doesn't exist, find() will return null.  We only
      // get here if something went wrong accessing the database
      log.error(
          "For the change {} of project {}: failed to resolve account {}.",
          changeNumber,
          project,
          accountName,
          e);
      return true;
    }
    return false;
  }

  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) {
      log.warn(
          "For the change {} of project {}: reviewer {} is neither an account nor a group.",
          changeNumber,
          project,
          group);
    } catch (NoSuchProjectException | IOException e) {
      log.error(
          "For the change {} of project {}: failed to list accounts for group {}.",
          changeNumber,
          project,
          group,
          e);
    }
  }
}
