// Copyright (C) 2015 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.api.change;

import static com.google.common.truth.Truth.assertThat;
import static com.google.gerrit.extensions.client.SubmitType.CHERRY_PICK;
import static com.google.gerrit.extensions.client.SubmitType.FAST_FORWARD_ONLY;
import static com.google.gerrit.extensions.client.SubmitType.MERGE_ALWAYS;
import static com.google.gerrit.extensions.client.SubmitType.MERGE_IF_NECESSARY;
import static com.google.gerrit.extensions.client.SubmitType.REBASE_ALWAYS;
import static com.google.gerrit.extensions.client.SubmitType.REBASE_IF_NECESSARY;

import com.google.common.collect.ImmutableList;
import com.google.gerrit.acceptance.AbstractDaemonTest;
import com.google.gerrit.acceptance.NoHttpd;
import com.google.gerrit.acceptance.PushOneCommit;
import com.google.gerrit.extensions.api.changes.ReviewInput;
import com.google.gerrit.extensions.api.projects.BranchInput;
import com.google.gerrit.extensions.client.SubmitType;
import com.google.gerrit.extensions.common.TestSubmitRuleInfo;
import com.google.gerrit.extensions.common.TestSubmitRuleInput;
import com.google.gerrit.extensions.restapi.ResourceConflictException;
import com.google.gerrit.extensions.restapi.RestApiException;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.RefNames;
import com.google.gerrit.server.git.meta.MetaDataUpdate;
import com.google.gerrit.server.git.meta.VersionedMetaData;
import com.google.gerrit.testing.ConfigSuite;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.errors.ConfigInvalidException;
import org.eclipse.jgit.lib.CommitBuilder;
import org.eclipse.jgit.lib.Config;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
import org.junit.Before;
import org.junit.Test;

@NoHttpd
public class SubmitTypeRuleIT extends AbstractDaemonTest {
  @ConfigSuite.Default
  public static Config submitWholeTopicEnabled() {
    return submitWholeTopicEnabledConfig();
  }

  private class RulesPl extends VersionedMetaData {
    private static final String FILENAME = "rules.pl";

    private String rule;

    @Override
    protected String getRefName() {
      return RefNames.REFS_CONFIG;
    }

    @Override
    protected void onLoad() throws IOException, ConfigInvalidException {
      rule = readUTF8(FILENAME);
    }

    @Override
    protected boolean onSave(CommitBuilder commit) throws IOException, ConfigInvalidException {
      TestSubmitRuleInput in = new TestSubmitRuleInput();
      in.rule = rule;
      try {
        gApi.changes().id(testChangeId.get()).current().testSubmitType(in);
      } catch (RestApiException e) {
        throw new ConfigInvalidException("Invalid submit type rule", e);
      }

      saveUTF8(FILENAME, rule);
      return true;
    }
  }

  private AtomicInteger fileCounter;
  private Change.Id testChangeId;

  @Before
  public void setUp() throws Exception {
    fileCounter = new AtomicInteger();
    gApi.projects().name(project.get()).branch("test").create(new BranchInput());
    testChangeId = createChange("test", "test change").getChange().getId();
  }

  private void setRulesPl(String rule) throws Exception {
    try (MetaDataUpdate md = metaDataUpdateFactory.create(project)) {
      RulesPl r = new RulesPl();
      r.load(md);
      r.rule = rule;
      r.commit(md);
    }
  }

  private static final String SUBMIT_TYPE_FROM_SUBJECT =
      "submit_type(fast_forward_only) :-"
          + "gerrit:commit_message(M),"
          + "regex_matches('.*FAST_FORWARD_ONLY.*', M),"
          + "!.\n"
          + "submit_type(merge_if_necessary) :-"
          + "gerrit:commit_message(M),"
          + "regex_matches('.*MERGE_IF_NECESSARY.*', M),"
          + "!.\n"
          + "submit_type(rebase_if_necessary) :-"
          + "gerrit:commit_message(M),"
          + "regex_matches('.*REBASE_IF_NECESSARY.*', M),"
          + "!.\n"
          + "submit_type(rebase_always) :-"
          + "gerrit:commit_message(M),"
          + "regex_matches('.*REBASE_ALWAYS.*', M),"
          + "!.\n"
          + "submit_type(merge_always) :-"
          + "gerrit:commit_message(M),"
          + "regex_matches('.*MERGE_ALWAYS.*', M),"
          + "!.\n"
          + "submit_type(cherry_pick) :-"
          + "gerrit:commit_message(M),"
          + "regex_matches('.*CHERRY_PICK.*', M),"
          + "!.\n"
          + "submit_type(T) :- gerrit:project_default_submit_type(T).";

  private PushOneCommit.Result createChange(String dest, String subject) throws Exception {
    PushOneCommit push =
        pushFactory.create(
            db,
            admin.getIdent(),
            testRepo,
            subject,
            "file" + fileCounter.incrementAndGet(),
            PushOneCommit.FILE_CONTENT);
    PushOneCommit.Result r = push.to("refs/for/" + dest);
    r.assertOkStatus();
    return r;
  }

  @Test
  public void unconditionalCherryPick() throws Exception {
    PushOneCommit.Result r = createChange();
    assertSubmitType(MERGE_IF_NECESSARY, r.getChangeId());
    setRulesPl("submit_type(cherry_pick).");
    assertSubmitType(CHERRY_PICK, r.getChangeId());
  }

  @Test
  public void submitTypeFromSubject() throws Exception {
    PushOneCommit.Result r1 = createChange("master", "Default 1");
    PushOneCommit.Result r2 = createChange("master", "FAST_FORWARD_ONLY 2");
    PushOneCommit.Result r3 = createChange("master", "MERGE_IF_NECESSARY 3");
    PushOneCommit.Result r4 = createChange("master", "REBASE_IF_NECESSARY 4");
    PushOneCommit.Result r5 = createChange("master", "REBASE_ALWAYS 5");
    PushOneCommit.Result r6 = createChange("master", "MERGE_ALWAYS 6");
    PushOneCommit.Result r7 = createChange("master", "CHERRY_PICK 7");

    assertSubmitType(MERGE_IF_NECESSARY, r1.getChangeId());
    assertSubmitType(MERGE_IF_NECESSARY, r2.getChangeId());
    assertSubmitType(MERGE_IF_NECESSARY, r3.getChangeId());
    assertSubmitType(MERGE_IF_NECESSARY, r4.getChangeId());
    assertSubmitType(MERGE_IF_NECESSARY, r5.getChangeId());
    assertSubmitType(MERGE_IF_NECESSARY, r6.getChangeId());
    assertSubmitType(MERGE_IF_NECESSARY, r7.getChangeId());

    setRulesPl(SUBMIT_TYPE_FROM_SUBJECT);

    assertSubmitType(MERGE_IF_NECESSARY, r1.getChangeId());
    assertSubmitType(FAST_FORWARD_ONLY, r2.getChangeId());
    assertSubmitType(MERGE_IF_NECESSARY, r3.getChangeId());
    assertSubmitType(REBASE_IF_NECESSARY, r4.getChangeId());
    assertSubmitType(REBASE_ALWAYS, r5.getChangeId());
    assertSubmitType(MERGE_ALWAYS, r6.getChangeId());
    assertSubmitType(CHERRY_PICK, r7.getChangeId());
  }

  @Test
  public void submitTypeIsUsedForSubmit() throws Exception {
    setRulesPl(SUBMIT_TYPE_FROM_SUBJECT);

    PushOneCommit.Result r = createChange("master", "CHERRY_PICK 1");

    gApi.changes().id(r.getChangeId()).current().review(ReviewInput.approve());
    gApi.changes().id(r.getChangeId()).current().submit();

    List<RevCommit> log = log("master", 1);
    assertThat(log.get(0).getShortMessage()).isEqualTo("CHERRY_PICK 1");
    assertThat(log.get(0).name()).isNotEqualTo(r.getCommit().name());
    assertThat(log.get(0).getFullMessage()).contains("Change-Id: " + r.getChangeId());
    assertThat(log.get(0).getFullMessage()).contains("Reviewed-on: ");
  }

  @Test
  public void mixingSubmitTypesAcrossBranchesSucceeds() throws Exception {
    setRulesPl(SUBMIT_TYPE_FROM_SUBJECT);

    PushOneCommit.Result r1 = createChange("master", "MERGE_IF_NECESSARY 1");

    RevCommit initialCommit = r1.getCommit().getParent(0);
    BranchInput bin = new BranchInput();
    bin.revision = initialCommit.name();
    gApi.projects().name(project.get()).branch("branch").create(bin);

    testRepo.reset(initialCommit);
    PushOneCommit.Result r2 = createChange("branch", "MERGE_ALWAYS 1");

    gApi.changes().id(r1.getChangeId()).topic(name("topic"));
    gApi.changes().id(r1.getChangeId()).current().review(ReviewInput.approve());
    gApi.changes().id(r2.getChangeId()).topic(name("topic"));
    gApi.changes().id(r2.getChangeId()).current().review(ReviewInput.approve());
    gApi.changes().id(r2.getChangeId()).current().submit();

    assertThat(log("master", 1).get(0).name()).isEqualTo(r1.getCommit().name());

    List<RevCommit> branchLog = log("branch", 1);
    assertThat(branchLog.get(0).getParents()).hasLength(2);
    assertThat(branchLog.get(0).getParent(1).name()).isEqualTo(r2.getCommit().name());
  }

  @Test
  public void mixingSubmitTypesOnOneBranchFails() throws Exception {
    setRulesPl(SUBMIT_TYPE_FROM_SUBJECT);

    PushOneCommit.Result r1 = createChange("master", "CHERRY_PICK 1");
    PushOneCommit.Result r2 = createChange("master", "MERGE_IF_NECESSARY 2");

    gApi.changes().id(r1.getChangeId()).current().review(ReviewInput.approve());
    gApi.changes().id(r2.getChangeId()).current().review(ReviewInput.approve());

    try {
      gApi.changes().id(r2.getChangeId()).current().submit();
      fail("Expected ResourceConflictException");
    } catch (ResourceConflictException e) {
      assertThat(e)
          .hasMessageThat()
          .isEqualTo(
              "Failed to submit 2 changes due to the following problems:\n"
                  + "Change "
                  + r1.getChange().getId()
                  + ": Change has submit type "
                  + "CHERRY_PICK, but previously chose submit type MERGE_IF_NECESSARY "
                  + "from change "
                  + r2.getChange().getId()
                  + " in the same batch");
    }
  }

  @Test
  public void invalidSubmitRuleWithNoRulesInProject() throws Exception {
    String changeId = createChange("master", "change 1").getChangeId();

    TestSubmitRuleInput in = new TestSubmitRuleInput();
    in.rule = "invalid prolog rule";
    // We have no rules.pl by default. The fact that the default rules are showing up here is a bug.
    List<TestSubmitRuleInfo> response = gApi.changes().id(changeId).current().testSubmitRule(in);
    assertThat(response).containsExactly(invalidPrologRuleInfo());
  }

  @Test
  public void invalidSubmitRuleWithRulesInProject() throws Exception {
    setRulesPl(SUBMIT_TYPE_FROM_SUBJECT);

    String changeId = createChange("master", "change 1").getChangeId();

    TestSubmitRuleInput in = new TestSubmitRuleInput();
    in.rule = "invalid prolog rule";
    List<TestSubmitRuleInfo> response = gApi.changes().id(changeId).current().testSubmitRule(in);
    assertThat(response).containsExactly(invalidPrologRuleInfo());
  }

  private static TestSubmitRuleInfo invalidPrologRuleInfo() {
    TestSubmitRuleInfo info = new TestSubmitRuleInfo();
    info.status = "RULE_ERROR";
    info.errorMessage = "operator expected after expression at: invalid prolog rule end_of_file.";
    return info;
  }

  private List<RevCommit> log(String commitish, int n) throws Exception {
    try (Repository repo = repoManager.openRepository(project);
        Git git = new Git(repo)) {
      ObjectId id = repo.resolve(commitish);
      assertThat(id).isNotNull();
      return ImmutableList.copyOf(git.log().add(id).setMaxCount(n).call());
    }
  }

  private void assertSubmitType(SubmitType expected, String id) throws Exception {
    assertThat(gApi.changes().id(id).current().submitType()).isEqualTo(expected);
  }
}
