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

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.client.Project.SubmitType;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.IdentifiedUser;

import org.eclipse.jgit.lib.ObjectInserter;
import org.eclipse.jgit.lib.PersonIdent;
import org.eclipse.jgit.lib.RefUpdate;
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 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 MergeUtil mergeUtil;
    protected final MergeSorter mergeSorter;

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

      this.repo = repo;
      this.rw = rw;
      this.inserter = inserter;
      this.canMergeFlag = canMergeFlag;
      this.alreadyAccepted = alreadyAccepted;
      this.destBranch = destBranch;
      this.mergeUtil = mergeUtil;
      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</code> if the given commit can be merged, otherwise
   *         <code>false</code>
   * @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</code>
   */
  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 RefUpdate.Result#LOCK_FAILURE} should be retried.
   *
   * May be overwritten by subclasses.
   *
   * @return <code>true</code> if a merge that failed with
   *         {@link RefUpdate.Result#LOCK_FAILURE} should be retried, otherwise
   *         <code>false</code>
   */
  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();
    }
  }
}
