// 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.acceptance.rest.project;

import static com.google.common.truth.Truth.assertThat;

import com.google.common.base.Strings;
import com.google.gerrit.acceptance.AbstractDaemonTest;
import com.google.gerrit.acceptance.PushOneCommit;
import com.google.gerrit.acceptance.RestResponse;
import com.google.gerrit.extensions.api.changes.ChangeApi;
import com.google.gerrit.extensions.api.changes.CherryPickInput;
import com.google.gerrit.extensions.api.changes.ReviewInput;
import com.google.gerrit.extensions.api.projects.BranchInput;
import com.google.gerrit.extensions.common.MergeableInfo;
import com.google.gerrit.reviewdb.client.Branch;

import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.transport.RefSpec;
import org.junit.Before;
import org.junit.Test;

public class CheckMergeabilityIT extends AbstractDaemonTest {

  private Branch.NameKey branch;

  @Before
  public void setUp() throws Exception {
    branch = new Branch.NameKey(project, "test");
    gApi.projects()
        .name(branch.getParentKey().get())
        .branch(branch.get()).create(new BranchInput());
  }

  @Test
  public void checkMergeableCommit() throws Exception {
    RevCommit initialHead = getRemoteHead();
    testRepo.branch("HEAD").commit().insertChangeId()
        .message("some change in a")
        .add("a.txt", "a contents ")
        .create();
    testRepo.git().push().setRemote("origin").setRefSpecs(
        new RefSpec("HEAD:refs/heads/master")).call();

    testRepo.reset(initialHead);
    testRepo.branch("HEAD").commit().insertChangeId()
        .message("some change in b")
        .add("b.txt", "b contents ")
        .create();
    testRepo.git().push().setRemote("origin").setRefSpecs(
        new RefSpec("HEAD:refs/heads/test")).call();

    assertMergeable("master", "test", "recursive");
  }

  @Test
  public void checkUnMergeableCommit() throws Exception {
    RevCommit initialHead = getRemoteHead();
    testRepo.branch("HEAD").commit().insertChangeId()
        .message("some change in a")
        .add("a.txt", "a contents ")
        .create();
    testRepo.git().push().setRemote("origin").setRefSpecs(
        new RefSpec("HEAD:refs/heads/master")).call();

    testRepo.reset(initialHead);
    testRepo.branch("HEAD").commit().insertChangeId()
        .message("some change in a too")
        .add("a.txt", "a contents too")
        .create();
    testRepo.git().push().setRemote("origin").setRefSpecs(
        new RefSpec("HEAD:refs/heads/test")).call();

    assertUnMergeable("master", "test", "recursive", "a.txt");
  }

  @Test
  public void checkOursMergeStrategy() throws Exception {
    RevCommit initialHead = getRemoteHead();
    testRepo.branch("HEAD").commit().insertChangeId()
        .message("some change in a")
        .add("a.txt", "a contents ")
        .create();
    testRepo.git().push().setRemote("origin").setRefSpecs(
        new RefSpec("HEAD:refs/heads/master")).call();

    testRepo.reset(initialHead);
    testRepo.branch("HEAD").commit().insertChangeId()
        .message("some change in a too")
        .add("a.txt", "a contents too")
        .create();
    testRepo.git().push().setRemote("origin").setRefSpecs(
        new RefSpec("HEAD:refs/heads/test")).call();

    assertMergeable("master", "test", "ours");
  }

  @Test
  public void checkAlreadyMergedCommit() throws Exception {
    ObjectId c0 = testRepo.branch("HEAD").commit().insertChangeId()
        .message("first commit")
        .add("a.txt", "a contents ")
        .create();
    testRepo.git().push().setRemote("origin").setRefSpecs(
        new RefSpec("HEAD:refs/heads/master")).call();

    testRepo.branch("HEAD").commit().insertChangeId()
        .message("second commit")
        .add("b.txt", "b contents ")
        .create();
    testRepo.git().push().setRemote("origin").setRefSpecs(
        new RefSpec("HEAD:refs/heads/master")).call();

    assertCommitMerged("master", c0.getName(), "");
  }

  @Test
  public void checkContentMergedCommit() throws Exception {
    testRepo.branch("HEAD").commit().insertChangeId()
        .message("first commit")
        .add("a.txt", "a contents ")
        .create();
    testRepo.git().push().setRemote("origin").setRefSpecs(
        new RefSpec("HEAD:refs/heads/master")).call();

    // create a change, and cherrypick into master
    PushOneCommit.Result cId = createChange();
    RevCommit commitId = cId.getCommit();
    CherryPickInput cpi = new CherryPickInput();
    cpi.destination = "master";
    cpi.message = "cherry pick the commit";
    ChangeApi orig = gApi.changes()
        .id(cId.getChangeId());
    ChangeApi cherry = orig.current().cherryPick(cpi);
    cherry.current().review(ReviewInput.approve());
    cherry.current().submit();

    ObjectId remoteId = getRemoteHead();
    assertThat(remoteId).isNotEqualTo(commitId);
    assertContentMerged("master", commitId.getName(), "recursive");
  }

  @Test
  public void checkInvalidSource() throws Exception {
    testRepo.branch("HEAD").commit().insertChangeId()
        .message("first commit")
        .add("a.txt", "a contents ")
        .create();
    testRepo.git().push().setRemote("origin").setRefSpecs(
        new RefSpec("HEAD:refs/heads/master")).call();

    assertBadRequest("master", "fdsafsdf", "recursive",
        "Cannot resolve 'fdsafsdf' to a commit");
  }

  @Test
  public void checkInvalidStrategy() throws Exception {
    RevCommit initialHead = getRemoteHead();
    testRepo.branch("HEAD").commit().insertChangeId()
        .message("first commit")
        .add("a.txt", "a contents ")
        .create();
    testRepo.git().push().setRemote("origin").setRefSpecs(
        new RefSpec("HEAD:refs/heads/master")).call();

    testRepo.reset(initialHead);
    testRepo.branch("HEAD").commit().insertChangeId()
        .message("some change in a too")
        .add("a.txt", "a contents too")
        .create();
    testRepo.git().push().setRemote("origin").setRefSpecs(
        new RefSpec("HEAD:refs/heads/test")).call();

    assertBadRequest("master", "test", "octopus",
        "invalid merge strategy: octopus");
  }

  private void assertMergeable(String targetBranch, String source,
      String strategy) throws Exception {
    MergeableInfo
        mergeableInfo = getMergeableInfo(targetBranch, source, strategy);
    assertThat(mergeableInfo.mergeable).isTrue();
  }

  private void assertUnMergeable(String targetBranch, String source,
      String strategy, String... conflicts) throws Exception {
    MergeableInfo mergeableInfo = getMergeableInfo(targetBranch, source, strategy);
    assertThat(mergeableInfo.mergeable).isFalse();
    assertThat(mergeableInfo.conflicts).containsExactly((Object[]) conflicts);
  }

  private void assertCommitMerged(String targetBranch, String source,
      String strategy) throws Exception {
    MergeableInfo
        mergeableInfo = getMergeableInfo(targetBranch, source, strategy);
    assertThat(mergeableInfo.mergeable).isTrue();
    assertThat(mergeableInfo.commitMerged).isTrue();
  }

  private void assertContentMerged(String targetBranch, String source,
      String strategy) throws Exception {
    MergeableInfo
        mergeableInfo = getMergeableInfo(targetBranch, source, strategy);
    assertThat(mergeableInfo.mergeable).isTrue();
    assertThat(mergeableInfo.contentMerged).isTrue();
  }

  private void assertBadRequest(String targetBranch, String source,
      String strategy, String errMsg) throws Exception {
    String url = "/projects/" + project.get() + "/branches/" + targetBranch;
    url += "/mergeable?source=" + source;
    if (!Strings.isNullOrEmpty(strategy)) {
      url += "&strategy=" + strategy;
    }

    RestResponse r = userRestSession.get(url);
    r.assertBadRequest();
    assertThat(r.getEntityContent()).isEqualTo(errMsg);
  }

  private MergeableInfo getMergeableInfo(String targetBranch, String source,
      String strategy) throws Exception {
    String url = "/projects/" + project.get() + "/branches/" + targetBranch;
    url += "/mergeable?source=" + source;
    if (!Strings.isNullOrEmpty(strategy)) {
      url += "&strategy=" + strategy;
    }

    RestResponse r = userRestSession.get(url);
    r.assertOK();
    MergeableInfo result = newGson().fromJson(r.getReader(), MergeableInfo.class);
    r.consume();
    return result;
  }
}
