// 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(
            admin.newIdent(),
            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);
  }
}
