// Copyright (C) 2017 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.project;

import com.google.common.collect.ImmutableList;
import com.google.common.flogger.FluentLogger;
import com.google.gerrit.entities.Project;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.logging.Metadata;
import com.google.gerrit.server.logging.TraceContext;
import com.google.gerrit.server.logging.TraceContext.TraceTimer;
import com.google.gerrit.server.permissions.PermissionBackend;
import com.google.gerrit.server.permissions.PermissionBackend.RefFilterOptions;
import com.google.gerrit.server.permissions.PermissionBackendException;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Optional;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.ReachabilityChecker;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevWalk;

/**
 * Report whether a commit is reachable from a set of commits. This is used for checking if a user
 * has read permissions on a commit.
 */
@Singleton
public class Reachable {
  private static final FluentLogger logger = FluentLogger.forEnclosingClass();

  private final PermissionBackend permissionBackend;

  @Inject
  Reachable(PermissionBackend permissionBackend) {
    this.permissionBackend = permissionBackend;
  }

  /**
   * @return true if a commit is reachable from a given set of refs. This method enforces
   *     permissions on the given set of refs and performs a reachability check. Tags are not
   *     filtered separately and will only be returned if reachable by a provided ref.
   */
  public boolean fromRefs(
      Project.NameKey project, Repository repo, RevCommit commit, List<Ref> refs) {
    return fromRefs(project, repo, commit, refs, Optional.empty());
  }

  boolean fromRefs(
      Project.NameKey project,
      Repository repo,
      RevCommit commit,
      List<Ref> refs,
      Optional<CurrentUser> optionalUserProvider) {
    try (RevWalk rw = new RevWalk(repo)) {
      Collection<Ref> filtered =
          optionalUserProvider
              .map(permissionBackend::user)
              .orElse(permissionBackend.currentUser())
              .project(project)
              .filter(refs, repo, RefFilterOptions.defaults());
      Collection<RevCommit> visible = new ArrayList<>();
      for (Ref r : filtered) {
        visible.add(rw.parseCommit(r.getObjectId()));
      }

      // The filtering above already produces a voluminous trace. To separate the permission check
      // from the reachability check, do the trace here:
      try (TraceTimer timer =
          TraceContext.newTimer(
              "ReachabilityChecker.areAllReachable",
              Metadata.builder().projectName(project.get()).resourceCount(refs.size()).build())) {
        ReachabilityChecker checker = rw.getObjectReader().createReachabilityChecker(rw);
        Optional<RevCommit> unreachable =
            checker.areAllReachable(ImmutableList.of(rw.parseCommit(commit)), visible.stream());
        return !unreachable.isPresent();
      }
    } catch (IOException | PermissionBackendException e) {
      logger.atSevere().withCause(e).log(
          "Cannot verify permissions to commit object %s in repository %s", commit.name(), project);
      return false;
    }
  }
}
