// Copyright (C) 2023 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.git;

import static com.google.common.truth.Truth.assertThat;
import static com.google.gerrit.testing.GerritJUnit.assertThrows;

import com.google.common.collect.ImmutableMap;
import com.google.gerrit.acceptance.PushOneCommit;
import com.google.gerrit.extensions.api.projects.BranchInput;
import com.google.gerrit.extensions.client.SubmitType;
import com.google.gerrit.extensions.common.ChangeInfo;
import com.google.gerrit.extensions.restapi.ResourceConflictException;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.revwalk.RevCommit;
import org.junit.Before;
import org.junit.Test;

/**
 * Verifies that gerrit correctly detects implicit merges on submit..
 *
 * <p>The setup creates a repository with 2 branches: master and target. Both branches have common
 * parent:
 *
 * <pre>{@code
 * master                target
 *  |                       |
 *  ----->base commit <------
 * }</pre>
 *
 * Tests use only MergeAlways strategy. All other submit strategies (except cherry pick and rebase
 * always) use the same checks on submit. The {@link ImplicitMergeOnSubmitExperimentsIT} validates
 * that the implicit merge check is applied to all strategies (except cherry pick and rebase always)
 * and {@link ImplicitMergeOnSubmitByCherryPickOrRebaseAlwaysIT} contains tests for the cherry pick
 * and rebase always strategies.
 */
public class ImplicitMergeOnSubmitIT extends AbstractImplicitMergeTest {
  private RevCommit masterTip;
  private RevCommit otherTip;
  RevCommit baseCommit;

  @Before
  public void setUp() throws Exception {
    setSubmitType(SubmitType.MERGE_ALWAYS);
    gApi.projects().name(project.get()).branch("other").create(new BranchInput());
    baseCommit =
        repo()
            .parseCommit(
                ObjectId.fromString(
                    gApi.projects().name(project.get()).branch("master").get().revision));
    masterTip =
        pushTo("refs/heads/master", ImmutableMap.of("master-file", "master-content"), baseCommit)
            .getCommit();
    otherTip =
        pushTo("refs/heads/other", ImmutableMap.of("target-file", "target1-content"), baseCommit)
            .getCommit();
  }

  @Test
  public void singleChangeImplicitMerge() throws Exception {
    PushOneCommit.Result implicitMerge = createApprovedChange("master", otherTip);
    assertSubmitRejectedWithImplicitMerge(implicitMerge.getChangeId());
  }

  @Test
  public void chainOfChangesImplicitMerge() throws Exception {
    PushOneCommit.Result implicitMerge = createApprovedChange("master", otherTip);
    PushOneCommit.Result c1 = createApprovedChange("master", implicitMerge);
    PushOneCommit.Result c2 = createApprovedChange("master", c1);
    assertSubmitRejectedWithImplicitMerge(implicitMerge.getChangeId());
    assertSubmitRejectedWithImplicitMerge(c1.getChangeId());
    assertSubmitRejectedWithImplicitMerge(c2.getChangeId());
  }

  @Test
  public void chainOfChangesOnTopOfTargetBranchTipNoImplicitMerge() throws Exception {
    PushOneCommit.Result c1 = createApprovedChange("master", masterTip);
    PushOneCommit.Result c2 = createApprovedChange("master", c1);
    PushOneCommit.Result c3 = createApprovedChange("master", c2);
    assertThatChangeSubmittable(c1.getChangeId());
    assertThatChangeSubmittable(c2.getChangeId());
    assertThatChangeSubmittable(c3.getChangeId());
  }

  @Test
  public void chainOfChangesNotOnTopOfTargetBranchTipNoImplicitMerge() throws Exception {
    // Add one more commit to master branch.
    pushTo("refs/heads/master", ImmutableMap.of(), masterTip);
    PushOneCommit.Result c1 = createApprovedChange("master", masterTip);
    PushOneCommit.Result c2 = createApprovedChange("master", c1);
    PushOneCommit.Result c3 = createApprovedChange("master", c2);
    assertThatChangeSubmittable(c1.getChangeId());
    assertThatChangeSubmittable(c2.getChangeId());
    assertThatChangeSubmittable(c3.getChangeId());
  }

  @Test
  public void chainOfChangesNotOnTopOfTargetBranchTipWithImplicitMerge() throws Exception {
    // Add one more commit to master branch.
    pushTo("refs/heads/master", ImmutableMap.of(), masterTip);
    PushOneCommit.Result implicitMerge = createApprovedChange("master", otherTip);
    PushOneCommit.Result c2 = createApprovedChange("master", implicitMerge);
    PushOneCommit.Result c3 = createApprovedChange("master", c2);
    assertSubmitRejectedWithImplicitMerge(implicitMerge.getChangeId());
    assertSubmitRejectedWithImplicitMerge(c2.getChangeId());
    assertSubmitRejectedWithImplicitMerge(c3.getChangeId());
  }

  @Test
  public void chainOfChangesEndsWithExplicitMerge_onlyExplcitMergeCanBeSubmitted()
      throws Exception {
    PushOneCommit.Result implicitMerge = createApprovedChange("master", otherTip);
    PushOneCommit.Result changeInChange = createApprovedChange("master", implicitMerge);
    PushOneCommit.Result explicitMerge =
        createApprovedChange("master", changeInChange.getCommit(), masterTip);
    assertSubmitRejectedWithImplicitMerge(implicitMerge.getChangeId());
    assertSubmitRejectedWithImplicitMerge(changeInChange.getChangeId());
    assertThatChangeSubmittable(explicitMerge.getChangeId());
  }

  @Test
  public void twoChainOfChangesSameTopic_oneChainImplicitMerge_rejectedOnSubmit() throws Exception {
    cfg.setBoolean("change", null, "submitWholeTopic", true);
    PushOneCommit.Result c1 = createApprovedChange("master", masterTip);
    PushOneCommit.Result c2 = createApprovedChange("master", c1);
    PushOneCommit.Result c3 = createApprovedChange("master", c2.getCommit());
    PushOneCommit.Result implicitMerge = createApprovedChange("master", otherTip);
    PushOneCommit.Result im1 = createApprovedChange("master", implicitMerge);
    PushOneCommit.Result im2 = createApprovedChange("master", im1.getCommit());
    // The AbstractDaemonTest doesn't fully reset gerrit; it creates a new project for each test
    // and doesn't remove changes created in tests. As a result, if the same topic is used in
    // several tests gerrit tries to submit all changes, including changes from other tests.
    // The name method returns name scoped to this test method .
    String topic = name("topic");
    gApi.changes().id(c1.getChangeId()).topic(topic);
    gApi.changes().id(c2.getChangeId()).topic(topic);
    gApi.changes().id(c3.getChangeId()).topic(topic);
    gApi.changes().id(implicitMerge.getChangeId()).topic(topic);
    gApi.changes().id(im1.getChangeId()).topic(topic);
    gApi.changes().id(im2.getChangeId()).topic(topic);

    assertSubmitRejectedWithImplicitMerge(c1.getChangeId());
  }

  @Test
  public void twoChainOfChangesSameTopic_noImplicitMerge_canSubmit() throws Exception {
    cfg.setBoolean("change", null, "submitWholeTopic", true);
    PushOneCommit.Result chain1change1 = createApprovedChange("master", masterTip);
    PushOneCommit.Result chain1change2 = createApprovedChange("master", chain1change1);
    PushOneCommit.Result chain1change3 = createApprovedChange("master", chain1change2);
    PushOneCommit.Result chain2change1 = createApprovedChange("master", masterTip);
    PushOneCommit.Result chain2change2 = createApprovedChange("master", chain2change1);
    PushOneCommit.Result chain2change3 = createApprovedChange("master", chain2change2);
    // The AbstractDaemonTest doesn't fully reset gerrit; it creates a new project for each test
    // and doesn't remove changes created in tests. As a result, if the same topic is used in
    // several tests gerrit tries to submit all changes, including changes from other tests.
    // The name method returns name scoped to this test method .
    String topic = name("topic");
    gApi.changes().id(chain1change1.getChangeId()).topic(topic);
    gApi.changes().id(chain1change2.getChangeId()).topic(topic);
    gApi.changes().id(chain1change3.getChangeId()).topic(topic);
    gApi.changes().id(chain2change1.getChangeId()).topic(topic);
    gApi.changes().id(chain2change2.getChangeId()).topic(topic);
    gApi.changes().id(chain2change3.getChangeId()).topic(topic);

    assertThatChangeSubmittable(chain1change1.getChangeId());
  }

  @Test
  public void twoChainOfChangesSameTopicNotOnTopOfBranch_noImplicitMerge_canSubmit()
      throws Exception {
    // Add one more commit to master branch.
    pushTo("refs/heads/master", ImmutableMap.of(), masterTip);
    cfg.setBoolean("change", null, "submitWholeTopic", true);
    PushOneCommit.Result chain1change1 = createApprovedChange("master", masterTip);
    PushOneCommit.Result chain1change2 = createApprovedChange("master", chain1change1);
    PushOneCommit.Result chain1change3 = createApprovedChange("master", chain1change2);
    PushOneCommit.Result chain2change1 = createApprovedChange("master", masterTip);
    PushOneCommit.Result chain2change2 = createApprovedChange("master", chain2change1);
    PushOneCommit.Result chain2change3 = createApprovedChange("master", chain2change2);
    // The AbstractDaemonTest doesn't fully reset gerrit; it creates a new project for each test
    // and doesn't remove changes created in tests. As a result, if the same topic is used in
    // several tests gerrit tries to submit all changes, including changes from other tests.
    // The name method returns name scoped to this test method .
    String topic = name("topic");
    gApi.changes().id(chain1change1.getChangeId()).topic(topic);
    gApi.changes().id(chain1change2.getChangeId()).topic(topic);
    gApi.changes().id(chain1change3.getChangeId()).topic(topic);
    gApi.changes().id(chain2change1.getChangeId()).topic(topic);
    gApi.changes().id(chain2change2.getChangeId()).topic(topic);
    gApi.changes().id(chain2change3.getChangeId()).topic(topic);

    assertThatChangeSubmittable(chain1change1.getChangeId());
  }

  @Test
  public void twoChainOfChangesEndsWithExplicitMergeSameTopicNotTipOfBranches_canBeSubmitted()
      throws Exception {
    cfg.setBoolean("change", null, "submitWholeTopic", true);
    // Add one more commit to master branch.
    pushTo("refs/heads/master", ImmutableMap.of(), masterTip);
    PushOneCommit.Result implicitMerge1 = createApprovedChange("master", otherTip);
    PushOneCommit.Result changeInChain1 = createApprovedChange("master", implicitMerge1);
    PushOneCommit.Result explicitMerge1 =
        createApprovedChange("master", changeInChain1.getCommit(), masterTip);
    PushOneCommit.Result implicitMerge2 = createApprovedChange("master", otherTip);
    PushOneCommit.Result changeInChain2 = createApprovedChange("master", implicitMerge2);
    PushOneCommit.Result explicitMerge2 =
        createApprovedChange("master", changeInChain2.getCommit(), masterTip);
    // The AbstractDaemonTest doesn't fully reset gerrit; it creates a new project for each test
    // and doesn't remove changes created in tests. As a result, if the same topic is used in
    // several tests gerrit tries to submit all changes, including changes from other tests.
    // The name method returns name scoped to this test method .
    String topic = name("topic");
    gApi.changes().id(implicitMerge1.getChangeId()).topic(topic);
    gApi.changes().id(changeInChain1.getChangeId()).topic(topic);
    gApi.changes().id(explicitMerge1.getChangeId()).topic(topic);
    gApi.changes().id(implicitMerge2.getChangeId()).topic(topic);
    gApi.changes().id(changeInChain2.getChangeId()).topic(topic);
    gApi.changes().id(explicitMerge2.getChangeId()).topic(topic);

    assertThatChangeSubmittable(explicitMerge2.getChangeId());
  }

  @Test
  public void twoChainOfChangesDifferentBranchesSameTopic_oneChainImplicitMerge_rejectedOnSubmit()
      throws Exception {
    cfg.setBoolean("change", null, "submitWholeTopic", true);
    PushOneCommit.Result implicitMerge = createApprovedChange("other", masterTip);
    PushOneCommit.Result im1 = createApprovedChange("other", implicitMerge);
    PushOneCommit.Result im2 = createApprovedChange("other", im1.getCommit());
    PushOneCommit.Result c1 = createApprovedChange("master", masterTip);
    PushOneCommit.Result c2 = createApprovedChange("master", c1);
    PushOneCommit.Result c3 = createApprovedChange("master", c2.getCommit());
    // The AbstractDaemonTest doesn't fully reset gerrit; it creates a new project for each test
    // and doesn't remove changes created in tests. As a result, if the same topic is used in
    // several tests gerrit tries to submit all changes, including changes from other tests.
    // The name method returns name scoped to this test method .
    String topic = name("topic");
    gApi.changes().id(implicitMerge.getChangeId()).topic(topic);
    gApi.changes().id(im1.getChangeId()).topic(topic);
    gApi.changes().id(im2.getChangeId()).topic(topic);
    gApi.changes().id(c1.getChangeId()).topic(topic);
    gApi.changes().id(c2.getChangeId()).topic(topic);
    gApi.changes().id(c3.getChangeId()).topic(topic);

    assertSubmitRejectedWithImplicitMerge(implicitMerge.getChangeId());
  }

  @Test
  public void explicitMergeOnTopOfChain_onlyTopSubmittable() throws Exception {
    PushOneCommit.Result implicitMerge = createApprovedChange("master", otherTip);
    PushOneCommit.Result im1 = createApprovedChange("master", implicitMerge);
    PushOneCommit.Result im2 = createApprovedChange("master", im1.getCommit());
    PushOneCommit.Result explicitMerge = createApprovedChange("master", masterTip, im2.getCommit());

    assertSubmitRejectedWithImplicitMerge(implicitMerge.getChangeId());
    assertSubmitRejectedWithImplicitMerge(im1.getChangeId());
    assertSubmitRejectedWithImplicitMerge(im2.getChangeId());
    assertThatChangeSubmittable(explicitMerge.getChangeId());
  }

  @Test
  public void explicitMergeOnTopOfChainParentIsNotBranchTip_onlyTopSubmittable() throws Exception {
    // Add one more commit to master and other branches.
    pushTo("refs/heads/master", ImmutableMap.of(), masterTip);
    pushTo("refs/heads/other", ImmutableMap.of(), otherTip);

    PushOneCommit.Result implicitMerge = createApprovedChange("master", otherTip);
    PushOneCommit.Result im1 = createApprovedChange("master", implicitMerge);
    PushOneCommit.Result im2 = createApprovedChange("master", im1.getCommit());
    PushOneCommit.Result explicitMerge = createApprovedChange("master", masterTip, im2.getCommit());

    assertSubmitRejectedWithImplicitMerge(implicitMerge.getChangeId());
    assertSubmitRejectedWithImplicitMerge(im1.getChangeId());
    assertSubmitRejectedWithImplicitMerge(im2.getChangeId());
    assertThatChangeSubmittable(explicitMerge.getChangeId());
  }

  @Test
  public void threeBranches_onlyExplicitCommitSubmittable() throws Exception {
    BranchInput bi = new BranchInput();
    bi.revision = baseCommit.getName();
    gApi.projects().name(project.get()).branch("third").create(bi);
    RevCommit thirdBranchTip =
        pushTo("refs/heads/third", ImmutableMap.of("third-file", "third-content"), baseCommit)
            .getCommit();

    PushOneCommit.Result explicitMerge = createApprovedChange("master", masterTip, otherTip);
    PushOneCommit.Result implicitMerge = createApprovedChange("master", otherTip, thirdBranchTip);
    PushOneCommit.Result explicitMerge2 =
        createApprovedChange("master", explicitMerge, implicitMerge);

    assertSubmitRejectedWithImplicitMerge(implicitMerge.getChangeId());
    assertThatChangeSubmittable(explicitMerge.getChangeId());
    assertThatChangeSubmittable(explicitMerge2.getChangeId());
  }

  private void assertSubmitRejectedWithImplicitMerge(String changeId) throws Exception {
    ResourceConflictException e =
        assertThrows(
            ResourceConflictException.class, () -> gApi.changes().id(changeId).current().submit());
    assertThat(e.getMessage()).contains("implicit merge");
  }

  private void assertThatChangeSubmittable(String changeId) throws Exception {
    ChangeInfo ci = gApi.changes().id(changeId).current().submit();
    assertThat(ci.submitted).isNotNull();
  }
}
