// Copyright (C) 2020 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.patch;

import com.google.gerrit.common.Nullable;
import com.google.gerrit.entities.Project;
import com.google.gerrit.entities.RefNames;
import com.google.gerrit.server.config.GerritServerConfig;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.git.InMemoryInserter;
import com.google.gerrit.server.update.RepoView;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import java.io.IOException;
import java.util.Optional;
import org.eclipse.jgit.lib.Config;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.ObjectInserter;
import org.eclipse.jgit.lib.ObjectReader;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevObject;
import org.eclipse.jgit.revwalk.RevWalk;

/** A utility class for computing the base commit / parent for a specific patchset commit. */
@Singleton
class BaseCommitUtil {
  private final AutoMerger autoMerger;
  private final GitRepositoryManager repoManager;

  /** If true, auto-merge results are stored in the repository. */
  private final boolean saveAutomerge;

  @Inject
  BaseCommitUtil(AutoMerger am, @GerritServerConfig Config cfg, GitRepositoryManager repoManager) {
    this.autoMerger = am;
    this.saveAutomerge = AutoMerger.cacheAutomerge(cfg);
    this.repoManager = repoManager;
  }

  RevObject getBaseCommit(Project.NameKey project, ObjectId newCommit, @Nullable Integer parentNum)
      throws IOException {
    try (Repository repo = repoManager.openRepository(project);
        ObjectInserter ins = newInserter(repo);
        ObjectReader reader = ins.newReader();
        RevWalk rw = new RevWalk(reader)) {
      return getParentCommit(repo, ins, rw, parentNum, newCommit);
    }
  }

  /**
   * Returns the number of parent commits of the commit represented by the commitId parameter.
   *
   * @param project a specific git repository.
   * @param commitId 20 bytes commitId SHA-1 hash.
   * @return an integer representing the number of parents of the designated commit.
   */
  int getNumParents(Project.NameKey project, ObjectId commitId) throws IOException {
    try (Repository repo = repoManager.openRepository(project);
        ObjectInserter ins = repo.newObjectInserter();
        ObjectReader reader = ins.newReader();
        RevWalk rw = new RevWalk(reader)) {
      RevCommit current = rw.parseCommit(commitId);
      return current.getParentCount();
    }
  }

  /**
   * Returns the parent commit Object of the commit represented by the commitId parameter.
   *
   * @param repo a git repository.
   * @param ins a git object inserter in the database.
   * @param rw a {@link RevWalk} object of the repository.
   * @param parentNum used to identify the parent number for merge commits. If parentNum is null and
   *     {@code commitId} has two parents, the auto-merge commit will be returned. If {@code
   *     commitId} has a single parent, it will be returned.
   * @param commitId 20 bytes commitId SHA-1 hash.
   * @return Returns the parent commit of the commit represented by the commitId parameter. Note
   *     that auto-merge is not supported for commits having more than two parents.
   */
  RevObject getParentCommit(
      Repository repo,
      ObjectInserter ins,
      RevWalk rw,
      @Nullable Integer parentNum,
      ObjectId commitId)
      throws IOException {
    RevCommit current = rw.parseCommit(commitId);
    switch (current.getParentCount()) {
      case 0:
        return rw.parseAny(emptyTree(ins));
      case 1:
        return current.getParent(0);
      default:
        if (parentNum != null) {
          RevCommit r = current.getParent(parentNum - 1);
          rw.parseBody(r);
          return r;
        }
        // Only support auto-merge for 2 parents, not octopus merges
        if (current.getParentCount() == 2) {
          if (!saveAutomerge) {
            throw new IOException(
                "diff against auto-merge commits is only supported if 'change.cacheAutomerge' config is set to true.");
          }
          // TODO(ghareeb): Avoid persisting auto-merge commits.
          return getAutoMergeFromGitOrCreate(repo, ins, rw, current);
        }
        return null;
    }
  }

  /**
   * Gets the auto-merge commit from git if it already exists. If not, the auto-merge is created,
   * persisted in git and the cache-automerge ref is updated for the merge commit.
   *
   * @return the auto-merge {@link RevCommit}
   */
  private RevCommit getAutoMergeFromGitOrCreate(
      Repository repo, ObjectInserter ins, RevWalk rw, RevCommit mergeCommit) throws IOException {
    String refName = RefNames.refsCacheAutomerge(mergeCommit.name());
    Optional<RevCommit> autoMergeCommit = autoMerger.lookupCommit(repo, rw, refName);
    if (autoMergeCommit.isPresent()) {
      return autoMergeCommit.get();
    }
    ObjectId autoMergeId =
        autoMerger.createAutoMergeCommit(new RepoView(repo, rw, ins), rw, ins, mergeCommit);
    ins.flush();
    return rw.parseCommit(autoMergeId);
  }

  private ObjectInserter newInserter(Repository repo) {
    return saveAutomerge ? repo.newObjectInserter() : new InMemoryInserter(repo);
  }

  private static ObjectId emptyTree(ObjectInserter ins) throws IOException {
    ObjectId id = ins.insert(Constants.OBJ_TREE, new byte[] {});
    ins.flush();
    return id;
  }
}
