// Copyright (C) 2016 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.project;

import com.google.gerrit.extensions.client.SubmitType;
import com.google.gerrit.extensions.common.MergeableInfo;
import com.google.gerrit.extensions.restapi.BadRequestException;
import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
import com.google.gerrit.extensions.restapi.RestReadView;
import com.google.gerrit.reviewdb.server.ReviewDb;
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.git.MergeUtil;
import com.google.inject.Inject;
import com.google.inject.Provider;
import java.io.IOException;
import org.eclipse.jgit.lib.Config;
import org.eclipse.jgit.lib.ObjectInserter;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.merge.Merger;
import org.eclipse.jgit.merge.ResolveMerger;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevWalk;
import org.kohsuke.args4j.Option;

/** Check the mergeability at current branch for a git object references expression. */
public class CheckMergeability implements RestReadView<BranchResource> {

  private String source;
  private String strategy;
  private SubmitType submitType;
  private final Provider<ReviewDb> db;

  @Option(
      name = "--source",
      metaVar = "COMMIT",
      usage =
          "the source reference to merge, which could be any git object "
              + "references expression, refer to "
              + "org.eclipse.jgit.lib.Repository#resolve(String)",
      required = true)
  public void setSource(String source) {
    this.source = source;
  }

  @Option(
      name = "--strategy",
      metaVar = "STRATEGY",
      usage = "name of the merge strategy, refer to org.eclipse.jgit.merge.MergeStrategy")
  public void setStrategy(String strategy) {
    this.strategy = strategy;
  }

  private final GitRepositoryManager gitManager;

  @Inject
  CheckMergeability(
      GitRepositoryManager gitManager, @GerritServerConfig Config cfg, Provider<ReviewDb> db) {
    this.gitManager = gitManager;
    this.strategy = MergeUtil.getMergeStrategy(cfg).getName();
    this.submitType = cfg.getEnum("project", null, "submitType", SubmitType.MERGE_IF_NECESSARY);
    this.db = db;
  }

  @Override
  public MergeableInfo apply(BranchResource resource)
      throws IOException, BadRequestException, ResourceNotFoundException {
    if (!(submitType.equals(SubmitType.MERGE_ALWAYS)
        || submitType.equals(SubmitType.MERGE_IF_NECESSARY))) {
      throw new BadRequestException("Submit type: " + submitType + " is not supported");
    }

    MergeableInfo result = new MergeableInfo();
    result.submitType = submitType;
    result.strategy = strategy;
    try (Repository git = gitManager.openRepository(resource.getNameKey());
        RevWalk rw = new RevWalk(git);
        ObjectInserter inserter = new InMemoryInserter(git)) {
      Merger m = MergeUtil.newMerger(git, inserter, strategy);

      Ref destRef = git.getRefDatabase().exactRef(resource.getRef());
      if (destRef == null) {
        throw new ResourceNotFoundException(resource.getRef());
      }

      RevCommit targetCommit = rw.parseCommit(destRef.getObjectId());
      RevCommit sourceCommit = MergeUtil.resolveCommit(git, rw, source);

      if (!resource.getControl().canReadCommit(db.get(), git, sourceCommit)) {
        throw new BadRequestException("do not have read permission for: " + source);
      }

      if (rw.isMergedInto(sourceCommit, targetCommit)) {
        result.mergeable = true;
        result.commitMerged = true;
        result.contentMerged = true;
        return result;
      }

      if (m.merge(false, targetCommit, sourceCommit)) {
        result.mergeable = true;
        result.commitMerged = false;
        result.contentMerged = m.getResultTreeId().equals(targetCommit.getTree());
      } else {
        result.mergeable = false;
        if (m instanceof ResolveMerger) {
          result.conflicts = ((ResolveMerger) m).getUnmergedPaths();
        }
      }
    } catch (IllegalArgumentException e) {
      throw new BadRequestException(e.getMessage());
    }
    return result;
  }
}
