// 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 static com.google.common.base.Preconditions.checkNotNull;

import com.google.common.collect.Sets;
import com.google.gerrit.extensions.api.changes.NotifyHandling;
import com.google.gerrit.extensions.client.SubmitType;
import com.google.gerrit.extensions.config.FactoryModule;
import com.google.gerrit.reviewdb.client.Branch;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.ApprovalsUtil;
import com.google.gerrit.server.ChangeMessagesUtil;
import com.google.gerrit.server.GerritPersonIdent;
import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.PatchSetUtil;
import com.google.gerrit.server.account.AccountCache;
import com.google.gerrit.server.change.RebaseChangeOp;
import com.google.gerrit.server.extensions.events.ChangeMerged;
import com.google.gerrit.server.git.BatchUpdate;
import com.google.gerrit.server.git.CodeReviewCommit;
import com.google.gerrit.server.git.CodeReviewCommit.CodeReviewRevWalk;
import com.google.gerrit.server.git.EmailMerge;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.git.IntegrationException;
import com.google.gerrit.server.git.LabelNormalizer;
import com.google.gerrit.server.git.MergeOp.CommitStatus;
import com.google.gerrit.server.git.MergeSorter;
import com.google.gerrit.server.git.MergeTip;
import com.google.gerrit.server.git.MergeUtil;
import com.google.gerrit.server.git.SubmoduleOp;
import com.google.gerrit.server.git.TagCache;
import com.google.gerrit.server.patch.PatchSetInfoFactory;
import com.google.gerrit.server.project.ChangeControl;
import com.google.gerrit.server.project.ProjectCache;
import com.google.gerrit.server.project.ProjectState;
import com.google.gerrit.server.util.RequestId;
import com.google.inject.Module;
import com.google.inject.assistedinject.Assisted;
import com.google.inject.assistedinject.AssistedInject;

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

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Set;

/**
 * Base class that submit strategies must extend.
 * <p>
 * A submit strategy for a certain {@link SubmitType} defines how the submitted
 * commits should be merged.
 */
public abstract class SubmitStrategy {
  public static Module module() {
    return new FactoryModule() {
      @Override
      protected void configure() {
        factory(SubmitStrategy.Arguments.Factory.class);
      }
    };
  }

  static class Arguments {
    interface Factory {
      Arguments create(
          SubmitType submitType,
          Branch.NameKey destBranch,
          CommitStatus commits,
          CodeReviewRevWalk rw,
          IdentifiedUser caller,
          MergeTip mergeTip,
          ObjectInserter inserter,
          Repository repo,
          RevFlag canMergeFlag,
          ReviewDb db,
          Set<RevCommit> alreadyAccepted,
          RequestId submissionId,
          NotifyHandling notifyHandling,
          SubmoduleOp submoduleOp);
    }

    final AccountCache accountCache;
    final ApprovalsUtil approvalsUtil;
    final BatchUpdate.Factory batchUpdateFactory;
    final ChangeControl.GenericFactory changeControlFactory;
    final ChangeMerged changeMerged;
    final ChangeMessagesUtil cmUtil;
    final EmailMerge.Factory mergedSenderFactory;
    final GitRepositoryManager repoManager;
    final LabelNormalizer labelNormalizer;
    final PatchSetInfoFactory patchSetInfoFactory;
    final PatchSetUtil psUtil;
    final ProjectCache projectCache;
    final PersonIdent serverIdent;
    final RebaseChangeOp.Factory rebaseFactory;
    final TagCache tagCache;

    final Branch.NameKey destBranch;
    final CodeReviewRevWalk rw;
    final CommitStatus commits;
    final IdentifiedUser caller;
    final MergeTip mergeTip;
    final ObjectInserter inserter;
    final Repository repo;
    final RevFlag canMergeFlag;
    final ReviewDb db;
    final Set<RevCommit> alreadyAccepted;
    final RequestId submissionId;
    final SubmitType submitType;
    final NotifyHandling notifyHandling;
    final SubmoduleOp submoduleOp;

    final ProjectState project;
    final MergeSorter mergeSorter;
    final MergeUtil mergeUtil;

    @AssistedInject
    Arguments(
        AccountCache accountCache,
        ApprovalsUtil approvalsUtil,
        BatchUpdate.Factory batchUpdateFactory,
        ChangeControl.GenericFactory changeControlFactory,
        ChangeMerged changeMerged,
        ChangeMessagesUtil cmUtil,
        EmailMerge.Factory mergedSenderFactory,
        GitRepositoryManager repoManager,
        LabelNormalizer labelNormalizer,
        MergeUtil.Factory mergeUtilFactory,
        PatchSetInfoFactory patchSetInfoFactory,
        PatchSetUtil psUtil,
        @GerritPersonIdent PersonIdent serverIdent,
        ProjectCache projectCache,
        RebaseChangeOp.Factory rebaseFactory,
        TagCache tagCache,
        @Assisted Branch.NameKey destBranch,
        @Assisted CommitStatus commits,
        @Assisted CodeReviewRevWalk rw,
        @Assisted IdentifiedUser caller,
        @Assisted MergeTip mergeTip,
        @Assisted ObjectInserter inserter,
        @Assisted Repository repo,
        @Assisted RevFlag canMergeFlag,
        @Assisted ReviewDb db,
        @Assisted Set<RevCommit> alreadyAccepted,
        @Assisted RequestId submissionId,
        @Assisted SubmitType submitType,
        @Assisted NotifyHandling notifyHandling,
        @Assisted SubmoduleOp submoduleOp) {
      this.accountCache = accountCache;
      this.approvalsUtil = approvalsUtil;
      this.batchUpdateFactory = batchUpdateFactory;
      this.changeControlFactory = changeControlFactory;
      this.changeMerged = changeMerged;
      this.mergedSenderFactory = mergedSenderFactory;
      this.repoManager = repoManager;
      this.cmUtil = cmUtil;
      this.labelNormalizer = labelNormalizer;
      this.patchSetInfoFactory = patchSetInfoFactory;
      this.psUtil = psUtil;
      this.projectCache = projectCache;
      this.rebaseFactory = rebaseFactory;
      this.tagCache = tagCache;

      this.serverIdent = serverIdent;
      this.destBranch = destBranch;
      this.commits = commits;
      this.rw = rw;
      this.caller = caller;
      this.mergeTip = mergeTip;
      this.inserter = inserter;
      this.repo = repo;
      this.canMergeFlag = canMergeFlag;
      this.db = db;
      this.alreadyAccepted = alreadyAccepted;
      this.submissionId = submissionId;
      this.submitType = submitType;
      this.notifyHandling = notifyHandling;
      this.submoduleOp = submoduleOp;

      this.project = checkNotNull(projectCache.get(destBranch.getParentKey()),
            "project not found: %s", destBranch.getParentKey());
      this.mergeSorter = new MergeSorter(rw, alreadyAccepted, canMergeFlag);
      this.mergeUtil = mergeUtilFactory.create(project);
    }
  }

  final Arguments args;

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

  /**
   * Add operations to a batch update that execute this submit strategy.
   * <p>
   * Guarantees exactly one op is added to the update for each change in the
   * input set.
   *
   * @param bu batch update to add operations to.
   * @param toMerge the set of submitted commits that should be merged using
   *     this submit strategy. Implementations are responsible for ordering of
   *     commits, and will not modify the input in place.
   * @throws IntegrationException if an error occurred initializing the
   *     operations (as opposed to an error during execution, which will be
   *     reported only when the batch update executes the operations).
   */
  public final void addOps(BatchUpdate bu, Set<CodeReviewCommit> toMerge)
      throws IntegrationException {
    List<SubmitStrategyOp> ops = buildOps(toMerge);
    Set<CodeReviewCommit> added = Sets.newHashSetWithExpectedSize(ops.size());

    for (SubmitStrategyOp op : ops) {
      added.add(op.getCommit());
    }

    // First add ops for any implicitly merged changes.
    List<CodeReviewCommit> difference =
        new ArrayList<>(Sets.difference(toMerge, added));
    Collections.reverse(difference);
    for (CodeReviewCommit c : difference) {
      bu.addOp(c.change().getId(), new ImplicitIntegrateOp(args, c));
    }

    // Then ops for explicitly merged changes
    for (SubmitStrategyOp op : ops) {
      bu.addOp(op.getId(), op);
    }
  }

  protected abstract List<SubmitStrategyOp> buildOps(
      Collection<CodeReviewCommit> toMerge) throws IntegrationException;
}
