// 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.git.strategy;

import com.google.gerrit.extensions.common.SubmitType;
import com.google.gerrit.reviewdb.client.Branch;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.PatchSetApproval;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.ApprovalsUtil;
import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.git.CodeReviewCommit;
import com.google.gerrit.server.git.MergeException;
import com.google.gerrit.server.git.MergeSorter;
import com.google.gerrit.server.git.MergeUtil;
import com.google.gerrit.server.index.ChangeIndexer;
import com.google.gerrit.server.project.ChangeControl;

import org.eclipse.jgit.lib.ObjectInserter;
import org.eclipse.jgit.lib.PersonIdent;
import org.eclipse.jgit.lib.RefUpdate.Result;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevFlag;
import org.eclipse.jgit.revwalk.RevWalk;

import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * Base class that submit strategies must extend. A submit strategy for a
 * certain {@link SubmitType} defines how the submitted commits should be
 * merged.
 */
public abstract class SubmitStrategy {

  private PersonIdent refLogIdent;

  static class Arguments {
    protected final IdentifiedUser.GenericFactory identifiedUserFactory;
    protected final PersonIdent myIdent;
    protected final ReviewDb db;
    protected final ChangeControl.GenericFactory changeControlFactory;

    protected final Repository repo;
    protected final RevWalk rw;
    protected final ObjectInserter inserter;
    protected final RevFlag canMergeFlag;
    protected final Set<RevCommit> alreadyAccepted;
    protected final Branch.NameKey destBranch;
    protected final ApprovalsUtil approvalsUtil;
    protected final MergeUtil mergeUtil;
    protected final ChangeIndexer indexer;
    protected final MergeSorter mergeSorter;

    Arguments(final IdentifiedUser.GenericFactory identifiedUserFactory,
        final PersonIdent myIdent, final ReviewDb db,
        final ChangeControl.GenericFactory changeControlFactory,
        final Repository repo, final RevWalk rw, final ObjectInserter inserter,
        final RevFlag canMergeFlag, final Set<RevCommit> alreadyAccepted,
        final Branch.NameKey destBranch, final ApprovalsUtil approvalsUtil,
        final MergeUtil mergeUtil, final ChangeIndexer indexer) {
      this.identifiedUserFactory = identifiedUserFactory;
      this.myIdent = myIdent;
      this.db = db;
      this.changeControlFactory = changeControlFactory;

      this.repo = repo;
      this.rw = rw;
      this.inserter = inserter;
      this.canMergeFlag = canMergeFlag;
      this.alreadyAccepted = alreadyAccepted;
      this.destBranch = destBranch;
      this.approvalsUtil = approvalsUtil;
      this.mergeUtil = mergeUtil;
      this.indexer = indexer;
      this.mergeSorter = new MergeSorter(rw, alreadyAccepted, canMergeFlag);
    }
  }

  protected final Arguments args;

  SubmitStrategy(final Arguments args) {
    this.args = args;
  }

  /**
   * Runs this submit strategy. If possible the provided commits will be merged
   * with this submit strategy.
   *
   * @param mergeTip the mergeTip
   * @param toMerge the list of submitted commits that should be merged using
   *        this submit strategy
   * @return the new mergeTip
   * @throws MergeException
   */
  public final CodeReviewCommit run(final CodeReviewCommit mergeTip,
      final List<CodeReviewCommit> toMerge) throws MergeException {
    refLogIdent = null;
    return _run(mergeTip, toMerge);
  }

  /**
   * Runs this submit strategy. If possible the provided commits will be merged
   * with this submit strategy.
   *
   * @param mergeTip the mergeTip
   * @param toMerge the list of submitted commits that should be merged using
   *        this submit strategy
   * @return the new mergeTip
   * @throws MergeException
   */
  protected abstract CodeReviewCommit _run(CodeReviewCommit mergeTip,
      List<CodeReviewCommit> toMerge) throws MergeException;

  /**
   * Checks whether the given commit can be merged.
   *
   * Subclasses must ensure that invoking this method does neither modify the
   * git repository nor the Gerrit database.
   *
   * @param mergeTip the mergeTip
   * @param toMerge the commit for which it should be checked whether it can be
   *        merged or not
   * @return {@code true} if the given commit can be merged, otherwise
   *         {@code false}
   * @throws MergeException
   */
  public abstract boolean dryRun(CodeReviewCommit mergeTip,
      CodeReviewCommit toMerge) throws MergeException;

  /**
   * Returns the PersonIdent that should be used for the ref log entries when
   * updating the destination branch. The ref log identity may be set after the
   * {@link #run(CodeReviewCommit, List)} method finished.
   *
   * Do only call this method after the {@link #run(CodeReviewCommit, List)}
   * method has been invoked.
   *
   * @return the ref log identity, may be {@code null}
   */
  public final PersonIdent getRefLogIdent() {
    return refLogIdent;
  }

  /**
   * Returns all commits that have been newly created for the changes that are
   * getting merged.
   *
   * By default this method is returning an empty map, but subclasses may
   * overwrite this method to provide newly created commits.
   *
   * Do only call this method after the {@link #run(CodeReviewCommit, List)}
   * method has been invoked.
   *
   * @return new commits created for changes that are getting merged
   */
  public Map<Change.Id, CodeReviewCommit> getNewCommits() {
    return Collections.emptyMap();
  }

  /**
   * Returns whether a merge that failed with
   * {@link Result#LOCK_FAILURE} should be retried.
   *
   * May be overwritten by subclasses.
   *
   * @return {@code true} if a merge that failed with
   *         {@link Result#LOCK_FAILURE} should be retried, otherwise
   *         {@code false}
   */
  public boolean retryOnLockFailure() {
    return true;
  }

  /**
   * Sets the ref log identity if it wasn't set yet.
   *
   * @param submitApproval the approval that submitted the patch set
   */
  protected final void setRefLogIdent(final PatchSetApproval submitApproval) {
    if (refLogIdent == null && submitApproval != null) {
      refLogIdent =
          args.identifiedUserFactory.create(submitApproval.getAccountId())
              .newRefLogIdent();
    }
  }
}
