// 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.common.truth.TruthJUnit.assume;
import static com.google.gerrit.server.util.CommitMessageUtil.generateChangeId;
import static com.google.gerrit.testing.GerritJUnit.assertThrows;

import com.google.common.collect.ImmutableMap;
import com.google.gerrit.acceptance.config.GerritConfig;
import com.google.gerrit.extensions.api.changes.ReviewInput;
import com.google.gerrit.extensions.client.SubmitType;
import com.google.gerrit.extensions.common.ChangeInfo;
import com.google.gerrit.extensions.restapi.ResourceConflictException;
import com.google.gerrit.testing.ConfigSuite;
import org.eclipse.jgit.lib.Config;
import org.eclipse.jgit.revwalk.RevCommit;
import org.junit.Before;
import org.junit.Test;

/**
 * Verifies that gerrit correctly rejects or submits implicit merges depending on experiments.
 *
 * <p>All tests use the same commit configuration (master branch is one commit ahead of stable
 * branch):
 *
 * <pre>{@code
 * change[1] (target - stable, explicit merge of stable branch and master branches)
 * |         \
 * |         change[0] (target - stable, i.e. implicit merge of master and stable branches)
 * |          |
 * |        master
 * |           |
 * stable <--- |
 * }</pre>
 */
public class ImplicitMergeOnSubmitExperimentsIT extends AbstractImplicitMergeTest {
  @Override
  protected boolean enableExperimentsRejectImplicitMergesOnMerge() {
    // Tests uses own experiment setup.
    return false;
  }

  @ConfigSuite.Configs
  public static ImmutableMap<String, Config> configs() {
    // The @RunWith(Parameterized.class) can't be used, because AbstractDaemonClass already
    // uses @RunWith(ConfigSuite.class). Emulate parameters using configs.
    ImmutableMap.Builder<String, Config> builder = ImmutableMap.builder();
    for (SubmitType submitType : SubmitType.values()) {
      if (submitType == SubmitType.INHERIT
          || submitType == SubmitType.CHERRY_PICK
          || submitType == SubmitType.REBASE_ALWAYS) {
        continue;
      }
      Config cfg = new Config();
      cfg.setString("test", null, "submitType", submitType.name());
      builder.put(String.format("submitType=%s", submitType), cfg);
    }
    return builder.buildOrThrow();
  }

  private String implicitMergeChangeId;
  private String explicitMergeChangeId;

  private SubmitType submitType;

  @Before
  public void setUp() throws Exception {
    // The ConfigSuite runner always adds a default config. Ignore it (submitType is not set for
    // it).
    assume().that(cfg.getString("test", null, "submitType")).isNotEmpty();
    RevCommit base = repo().parseCommit(repo().exactRef("HEAD").getObjectId());
    RevCommit stableBranchTip =
        pushTo("refs/heads/stable", ImmutableMap.of("stable-content", "stable-first-line\n"), base)
            .getCommit();
    RevCommit masterBranchTip =
        pushTo(
                "refs/heads/master",
                ImmutableMap.of("master-content", "master-first-line\n"),
                stableBranchTip)
            .getCommit();
    implicitMergeChangeId = "I" + generateChangeId().name();
    RevCommit implicitMergeChange =
        createChangeWithoutPush(
            implicitMergeChangeId,
            ImmutableMap.of("master-content2", "added-by-implicit-merge\n"),
            masterBranchTip);
    explicitMergeChangeId =
        pushTo(
                "refs/for/stable",
                ImmutableMap.of("stable-content", "stable-first-line\nadded-by-explicit-merge\n"),
                implicitMergeChange,
                stableBranchTip)
            .getChangeId();
    gApi.changes().id(implicitMergeChangeId).current().review(ReviewInput.approve());
    gApi.changes().id(explicitMergeChangeId).current().review(ReviewInput.approve());
    submitType = SubmitType.valueOf(cfg.getString("test", null, "submitType"));
    setSubmitType(submitType);
  }

  @Test
  @GerritConfig(
      name = "experiments.enabled",
      values = {
        "GerritBackendFeature__check_implicit_merges_on_merge",
        "GerritBackendFeature__reject_implicit_merges_on_merge",
        "GerritBackendFeature__always_reject_implicit_merges_on_merge"
      })
  public void alwaysRejectOnMerge_rejectImplicitMergeFalse_rejectImplicitMergeOnSubmit()
      throws Exception {
    setRejectImplicitMerges(/*reject=*/ false);
    assertThatImplicitMergeSubmitRejected();
  }

  @Test
  @GerritConfig(
      name = "experiments.enabled",
      values = {
        "GerritBackendFeature__check_implicit_merges_on_merge",
        "GerritBackendFeature__reject_implicit_merges_on_merge",
        "GerritBackendFeature__always_reject_implicit_merges_on_merge"
      })
  public void alwaysRejectOnMerge_rejectImplicitMergeFalse_canSubmitExplicitMerge()
      throws Exception {
    setRejectImplicitMerges(/*reject=*/ false);
    assertThatExcplicitMergeSubmitAllowed();
  }

  @Test
  @GerritConfig(
      name = "experiments.enabled",
      values = {
        "GerritBackendFeature__check_implicit_merges_on_merge",
        "GerritBackendFeature__reject_implicit_merges_on_merge",
        "GerritBackendFeature__always_reject_implicit_merges_on_merge"
      })
  public void alwaysRejectOnMerge_rejectImplicitMergeTrue_rejectImplicitMergeOnSubmit()
      throws Exception {
    setRejectImplicitMerges(/*reject=*/ true);
    assertThatImplicitMergeSubmitRejected();
  }

  @Test
  @GerritConfig(
      name = "experiments.enabled",
      values = {
        "GerritBackendFeature__check_implicit_merges_on_merge",
        "GerritBackendFeature__reject_implicit_merges_on_merge",
        "GerritBackendFeature__always_reject_implicit_merges_on_merge"
      })
  public void alwaysRejectOnMerge_rejectImplicitMergeTrue_canSubmitExplicitMerge()
      throws Exception {
    setRejectImplicitMerges(/*reject=*/ true);
    assertThatExcplicitMergeSubmitAllowed();
  }

  @Test
  @GerritConfig(
      name = "experiments.enabled",
      values = {
        "GerritBackendFeature__check_implicit_merges_on_merge",
        "GerritBackendFeature__reject_implicit_merges_on_merge",
      })
  public void rejectOnMerge_rejectImplicitMergeFalse_canSubmitImplicitMerge() throws Exception {
    setRejectImplicitMerges(/*reject=*/ false);
    assertThatImplicitMergeSubmitAllowed();
  }

  @Test
  @GerritConfig(
      name = "experiments.enabled",
      values = {
        "GerritBackendFeature__check_implicit_merges_on_merge",
        "GerritBackendFeature__reject_implicit_merges_on_merge",
      })
  public void rejectOnMerge_rejectImplicitMergeFalse_canSubmitExplicitMerge() throws Exception {
    setRejectImplicitMerges(/*reject=*/ false);
    assertThatExcplicitMergeSubmitAllowed();
  }

  @Test
  @GerritConfig(
      name = "experiments.enabled",
      values = {
        "GerritBackendFeature__check_implicit_merges_on_merge",
        "GerritBackendFeature__reject_implicit_merges_on_merge",
      })
  public void rejectOnMerge_rejectImplicitMergeTrue_rejectImplicitMergeOnSubmit() throws Exception {
    setRejectImplicitMerges(/*reject=*/ true);
    assertThatImplicitMergeSubmitRejected();
  }

  @Test
  @GerritConfig(
      name = "experiments.enabled",
      values = {
        "GerritBackendFeature__check_implicit_merges_on_merge",
        "GerritBackendFeature__reject_implicit_merges_on_merge",
      })
  public void rejectOnMerge_rejectImplicitMergeTrue_canSubmitExplicitMerge() throws Exception {
    setRejectImplicitMerges(/*reject=*/ true);
    assertThatExcplicitMergeSubmitAllowed();
  }

  @Test
  @GerritConfig(
      name = "experiments.enabled",
      values = {
        "GerritBackendFeature__check_implicit_merges_on_merge",
      })
  public void checkOnly_rejectImplicitMergeFalse_canSubmitImplicitMerge() throws Exception {
    setRejectImplicitMerges(/*reject=*/ false);
    assertThatImplicitMergeSubmitAllowed();
  }

  @Test
  @GerritConfig(
      name = "experiments.enabled",
      values = {
        "GerritBackendFeature__check_implicit_merges_on_merge",
      })
  public void checkOnly_rejectImplicitMergeFalse_canSubmitExplicitMerge() throws Exception {
    setRejectImplicitMerges(/*reject=*/ false);
    assertThatExcplicitMergeSubmitAllowed();
  }

  @Test
  @GerritConfig(
      name = "experiments.enabled",
      values = {
        "GerritBackendFeature__check_implicit_merges_on_merge",
      })
  public void checkOnly_rejectImplicitMergeTrue_canSubmitImplicitMerge() throws Exception {
    setRejectImplicitMerges(/*reject=*/ true);
    assertThatImplicitMergeSubmitAllowed();
  }

  @Test
  @GerritConfig(
      name = "experiments.enabled",
      values = {
        "GerritBackendFeature__check_implicit_merges_on_merge",
      })
  public void checkOnly_rejectImplicitMergeTrue_canSubmitExplicitMerge() throws Exception {
    setRejectImplicitMerges(/*reject=*/ true);
    assertThatExcplicitMergeSubmitAllowed();
  }

  @Test
  public void noExperiments_rejectImplicitMergeFalse_canSubmitImplicitMerge() throws Exception {
    setRejectImplicitMerges(/*reject=*/ false);
    assertThatImplicitMergeSubmitAllowed();
  }

  @Test
  public void noExperiments_rejectImplicitMergeFalse_canSubmitExplicitMerge() throws Exception {
    setRejectImplicitMerges(/*reject=*/ false);
    assertThatExcplicitMergeSubmitAllowed();
  }

  @Test
  public void noExperiments_rejectImplicitMergeTrue_canSubmitImplicitMerge() throws Exception {
    setRejectImplicitMerges(/*reject=*/ true);
    assertThatImplicitMergeSubmitAllowed();
  }

  @Test
  public void noExperiments_rejectImplicitMergeTrue_canSubmitExplicitMerge() throws Exception {
    setRejectImplicitMerges(/*reject=*/ true);
    assertThatExcplicitMergeSubmitAllowed();
  }

  private void assertThatImplicitMergeSubmitRejected() throws Exception {
    ResourceConflictException e =
        assertThrows(
            ResourceConflictException.class,
            () -> gApi.changes().id(implicitMergeChangeId).current().submit());
    assertThat(e.getMessage().toLowerCase()).contains("submit makes implicit merge to the branch");
    ChangeInfo ci = gApi.changes().id(implicitMergeChangeId).info();
    assertThat(ci.submitted).isNull();
    assertThat(getRemoteBranchRootPathContent("refs/heads/stable"))
        .containsExactly("stable-content", "stable-first-line\n");
  }

  private void assertThatImplicitMergeSubmitAllowed() throws Exception {
    gApi.changes().id(implicitMergeChangeId).current().submit();

    ChangeInfo ci = gApi.changes().id(implicitMergeChangeId).info();
    assertThat(ci.submitted).isNotNull();
    assertThat(ci.submitter).isNotNull();
    assertThat(ci.submitter._accountId)
        .isEqualTo(localCtx.getContext().getUser().getAccountId().get());

    if (submitType != SubmitType.REBASE_ALWAYS) {
      assertThat(getRemoteBranchRootPathContent("refs/heads/stable"))
          .containsExactly(
              "master-content", "master-first-line\n",
              "master-content2", "added-by-implicit-merge\n",
              "stable-content", "stable-first-line\n");
    } else {
      assertThat(getRemoteBranchRootPathContent("refs/heads/stable"))
          .containsExactly(
              "master-content2", "added-by-implicit-merge\n",
              "stable-content", "stable-first-line\n");
    }
  }

  private void assertThatExcplicitMergeSubmitAllowed() throws Exception {
    gApi.changes().id(explicitMergeChangeId).current().submit();

    ChangeInfo ci = gApi.changes().id(explicitMergeChangeId).info();
    assertThat(ci.submitted).isNotNull();
    assertThat(ci.submitter).isNotNull();
    assertThat(ci.submitter._accountId)
        .isEqualTo(localCtx.getContext().getUser().getAccountId().get());
    assertThat(getRemoteBranchRootPathContent("refs/heads/stable"))
        .containsExactly(
            "master-content", "master-first-line\n",
            "master-content2", "added-by-implicit-merge\n",
            "stable-content", "stable-first-line\nadded-by-explicit-merge\n");
  }
}
