// Copyright (C) 2014 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.googlesource.gerrit.plugins.batch.util;

import com.google.gerrit.common.Nullable;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.server.GerritPersonIdent;
import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.git.IntegrationException;
import com.google.inject.Inject;
import com.google.inject.assistedinject.Assisted;
import java.io.IOException;
import java.sql.Timestamp;
import java.util.concurrent.Callable;
import org.eclipse.jgit.lib.CommitBuilder;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.ObjectInserter;
import org.eclipse.jgit.lib.PersonIdent;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.merge.MergeStrategy;
import org.eclipse.jgit.merge.Merger;
import org.eclipse.jgit.merge.ThreeWayMerger;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevWalk;
import org.eclipse.jgit.util.StringUtils;

public class MergeBuilder implements Callable<ObjectId> {
  /**
   * The modes available for fast forward merges corresponding to the --ff, --no-ff and --ff-only
   * options
   */
  public static enum FastForwardMode {
    /**
     * Corresponds to the default --ff option (for a fast forward update the branch pointer only).
     */
    FF("ff"),
    /** Corresponds to the --no-ff option (create a merge commit even for a fast forward). */
    NO_FF("no-ff"),
    /**
     * Corresponds to the --ff-only option (abort unless the merge is a fast forward or branch is
     * already up-to-date).
     */
    FF_ONLY("ff-only");
    public final String name;

    private FastForwardMode(final String name) {
      this.name = name;
    }

    public String getName() {
      return name;
    }

    public static FastForwardMode fromString(String str) {
      if (StringUtils.isEmptyOrNull(str)) {
        return null;
      }
      for (FastForwardMode mode : FastForwardMode.values()) {
        if (mode.getName().equalsIgnoreCase(str)) {
          return mode;
        }
      }
      return null;
    }
  }

  public interface Factory {
    MergeBuilder create(
        @Assisted Project.NameKey project,
        @Assisted("message") @Nullable String message,
        @Assisted @Nullable MergeStrategy strategy,
        @Assisted @Nullable FastForwardMode fastForwardMode,
        @Assisted("firstParent") ObjectId firstParent,
        @Assisted("secondParent") ObjectId secondParent);
  }

  protected final GitRepositoryManager repoManager;
  protected final PersonIdent gerrit;
  protected final IdentifiedUser user;
  protected final Project.NameKey project;
  protected String message;
  protected final MergeStrategy strategy;
  protected FastForwardMode fastForwardMode = FastForwardMode.FF;
  protected final ObjectId firstParent;
  protected final ObjectId secondParent;

  @Inject
  MergeBuilder(
      GitRepositoryManager repoManager,
      @GerritPersonIdent PersonIdent gerrit,
      IdentifiedUser user,
      @Assisted Project.NameKey project,
      @Assisted("message") @Nullable String message,
      @Assisted @Nullable MergeStrategy strategy,
      @Assisted @Nullable FastForwardMode fastForwardMode,
      @Assisted("firstParent") ObjectId firstParent,
      @Assisted("secondParent") ObjectId secondParent) {
    this.repoManager = repoManager;
    this.gerrit = gerrit;
    this.user = user;
    this.project = project;
    this.message = message;
    this.strategy = strategy;
    if (fastForwardMode != null) {
      this.fastForwardMode = fastForwardMode;
    }
    this.firstParent = firstParent;
    this.secondParent = secondParent;
  }

  @Override
  public ObjectId call() throws IOException, IntegrationException {
    try (Repository repo = repoManager.openRepository(project)) {
      return build(repo);
    }
  }

  public ObjectId build(Repository repo) throws IOException, IntegrationException {
    try (RevWalk revWalk = new RevWalk(repo)) {
      RevCommit firstParentCommit = revWalk.lookupCommit(firstParent);
      RevCommit secondParentCommit = revWalk.lookupCommit(secondParent);
      if (revWalk.isMergedInto(secondParentCommit, firstParentCommit)) {
        return firstParent; // already up to date
      }
      if (fastForwardMode != FastForwardMode.NO_FF
          && revWalk.isMergedInto(firstParentCommit, secondParentCommit)) {
        return secondParent; // Fast forward merge
      }
      if (fastForwardMode == FastForwardMode.FF_ONLY) {
        throw new IntegrationException("Merge aborted"); // because not FF
      }
      return merge(repo, revWalk);
    }
  }

  protected ObjectId merge(Repository repo, RevWalk revWalk)
      throws IOException, IntegrationException {
    ThreeWayMerger merger = getMerger(repo);
    if (!merger.merge(firstParent, secondParent)) {
      throw new IntegrationException("Merge conflict");
    }
    message = defaultMessage(revWalk, message);
    return insert(merger, buildCommit(merger));
  }

  protected ThreeWayMerger getMerger(Repository repo) {
    if (strategy == MergeStrategy.RESOLVE) {
      return MergeStrategy.RESOLVE.newMerger(repo, true);
    } else {
      return MergeStrategy.SIMPLE_TWO_WAY_IN_CORE.newMerger(repo);
    }
  }

  protected CommitBuilder buildCommit(Merger merger) {
    final CommitBuilder mergeCommit = new CommitBuilder();
    mergeCommit.setTreeId(merger.getResultTreeId());
    mergeCommit.setParentIds(firstParent, secondParent);
    mergeCommit.setAuthor(
        user.newCommitterIdent(new Timestamp(System.currentTimeMillis()), gerrit.getTimeZone()));
    mergeCommit.setCommitter(gerrit);
    mergeCommit.setMessage(message);
    return mergeCommit;
  }

  protected String defaultMessage(RevWalk walk, String message) {
    if (message == null) {
      try {
        message = walk.parseCommit(secondParent).getShortMessage();
      } catch (Exception e) {
        message = secondParent.getName();
      }
      message = "Merge \"" + message + "\"";
    }
    return message;
  }

  protected ObjectId insert(Merger merger, CommitBuilder commit) throws IOException {
    try (ObjectInserter objInserter = merger.getObjectInserter()) {
      ObjectId mergeCommitId = objInserter.insert(commit);
      objInserter.flush();
      return mergeCommitId;
    }
  }
}
