// 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.change;

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

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.client.ChangeStatus;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.server.permissions.PermissionBackendException;
import com.google.gerrit.server.query.change.ChangeData;
import com.google.gerrit.server.restapi.change.Submit;
import com.google.gerrit.server.submit.ChangeSet;
import com.google.gerrit.server.submit.MergeSuperSet;
import com.google.gerrit.testing.ConfigSuite;
import com.google.inject.Inject;
import com.google.inject.Provider;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.eclipse.jgit.errors.IncorrectObjectTypeException;
import org.eclipse.jgit.errors.MissingObjectException;
import org.eclipse.jgit.internal.storage.dfs.InMemoryRepository;
import org.eclipse.jgit.junit.TestRepository;
import org.eclipse.jgit.lib.Config;
import org.eclipse.jgit.revwalk.RevCommit;
import org.junit.Test;

@NoHttpd
public class SubmitResolvingMergeCommitIT extends AbstractDaemonTest {
  @Inject private Provider<MergeSuperSet> mergeSuperSet;

  @Inject private Submit submit;

  @ConfigSuite.Default
  public static Config submitWholeTopicEnabled() {
    return submitWholeTopicEnabledConfig();
  }

  @Test
  public void resolvingMergeCommitAtEndOfChain() throws Exception {
    /*
      A <- B <- C <------- D
      ^                    ^
      |                    |
      E <- F <- G <- H <-- M*

      G has a conflict with C and is resolved in M which is a merge
      commit of H and D.
    */

    PushOneCommit.Result a = createChange("A");
    PushOneCommit.Result b =
        createChange("B", "new.txt", "No conflict line", ImmutableList.of(a.getCommit()));
    PushOneCommit.Result c = createChange("C", ImmutableList.of(b.getCommit()));
    PushOneCommit.Result d = createChange("D", ImmutableList.of(c.getCommit()));

    PushOneCommit.Result e = createChange("E", ImmutableList.of(a.getCommit()));
    PushOneCommit.Result f = createChange("F", ImmutableList.of(e.getCommit()));
    PushOneCommit.Result g =
        createChange("G", "new.txt", "Conflicting line", ImmutableList.of(f.getCommit()));
    PushOneCommit.Result h = createChange("H", ImmutableList.of(g.getCommit()));

    approve(a.getChangeId());
    approve(b.getChangeId());
    approve(c.getChangeId());
    approve(d.getChangeId());
    submit(d.getChangeId());

    approve(e.getChangeId());
    approve(f.getChangeId());
    approve(g.getChangeId());
    approve(h.getChangeId());

    assertMergeable(e.getChange());
    assertMergeable(f.getChange());
    assertNotMergeable(g.getChange());
    assertNotMergeable(h.getChange());

    PushOneCommit.Result m =
        createChange(
            "M", "new.txt", "Resolved conflict", ImmutableList.of(d.getCommit(), h.getCommit()));
    approve(m.getChangeId());

    assertChangeSetMergeable(m.getChange(), true);

    assertMergeable(m.getChange());
    submit(m.getChangeId());

    assertMerged(e.getChangeId());
    assertMerged(f.getChangeId());
    assertMerged(g.getChangeId());
    assertMerged(h.getChangeId());
    assertMerged(m.getChangeId());
  }

  @Test
  public void resolvingMergeCommitComingBeforeConflict() throws Exception {
    /*
      A <- B <- C <- D
      ^    ^
      |    |
      E <- F* <- G

      F is a merge commit of E and B and resolves any conflict.
      However G is conflicting with C.
    */

    PushOneCommit.Result a = createChange("A");
    PushOneCommit.Result b =
        createChange("B", "new.txt", "No conflict line", ImmutableList.of(a.getCommit()));
    PushOneCommit.Result c =
        createChange("C", "new.txt", "No conflict line #2", ImmutableList.of(b.getCommit()));
    PushOneCommit.Result d = createChange("D", ImmutableList.of(c.getCommit()));
    PushOneCommit.Result e =
        createChange("E", "new.txt", "Conflicting line", ImmutableList.of(a.getCommit()));
    PushOneCommit.Result f =
        createChange(
            "F", "new.txt", "Resolved conflict", ImmutableList.of(b.getCommit(), e.getCommit()));
    PushOneCommit.Result g =
        createChange("G", "new.txt", "Conflicting line #2", ImmutableList.of(f.getCommit()));

    assertMergeable(e.getChange());

    approve(a.getChangeId());
    approve(b.getChangeId());
    submit(b.getChangeId());

    assertNotMergeable(e.getChange());
    assertMergeable(f.getChange());
    assertMergeable(g.getChange());

    approve(c.getChangeId());
    approve(d.getChangeId());
    submit(d.getChangeId());

    approve(e.getChangeId());
    approve(f.getChangeId());
    approve(g.getChangeId());

    assertNotMergeable(g.getChange());
    assertChangeSetMergeable(g.getChange(), false);
  }

  @Test
  public void resolvingMergeCommitWithTopics() throws Exception {
    /*
      Project1:
        A <- B <-- C <---
        ^    ^          |
        |    |          |
        E <- F* <- G <- L*

      G clashes with C, and F resolves the clashes between E and B.
      Later, L resolves the clashes between C and G.

      Project2:
        H <- I
        ^    ^
        |    |
        J <- K*

      J clashes with I, and K resolves all problems.
      G, K and L are in the same topic.
    */
    assume().that(isSubmitWholeTopicEnabled()).isTrue();

    String project1Name = name("Project1");
    String project2Name = name("Project2");
    gApi.projects().create(project1Name);
    gApi.projects().create(project2Name);
    TestRepository<InMemoryRepository> project1 = cloneProject(Project.nameKey(project1Name));
    TestRepository<InMemoryRepository> project2 = cloneProject(Project.nameKey(project2Name));

    PushOneCommit.Result a = createChange(project1, "A");
    PushOneCommit.Result b =
        createChange(project1, "B", "new.txt", "No conflict line", ImmutableList.of(a.getCommit()));
    PushOneCommit.Result c =
        createChange(
            project1, "C", "new.txt", "No conflict line #2", ImmutableList.of(b.getCommit()));

    approve(a.getChangeId());
    approve(b.getChangeId());
    approve(c.getChangeId());
    submit(c.getChangeId());

    PushOneCommit.Result e =
        createChange(project1, "E", "new.txt", "Conflicting line", ImmutableList.of(a.getCommit()));
    PushOneCommit.Result f =
        createChange(
            project1,
            "F",
            "new.txt",
            "Resolved conflict",
            ImmutableList.of(b.getCommit(), e.getCommit()));
    PushOneCommit.Result g =
        createChange(
            project1,
            "G",
            "new.txt",
            "Conflicting line #2",
            ImmutableList.of(f.getCommit()),
            "refs/for/master/" + name("topic1"));

    PushOneCommit.Result h = createChange(project2, "H");
    PushOneCommit.Result i =
        createChange(project2, "I", "new.txt", "No conflict line", ImmutableList.of(h.getCommit()));
    PushOneCommit.Result j =
        createChange(project2, "J", "new.txt", "Conflicting line", ImmutableList.of(h.getCommit()));
    PushOneCommit.Result k =
        createChange(
            project2,
            "K",
            "new.txt",
            "Sadly conflicting topic-wise",
            ImmutableList.of(i.getCommit(), j.getCommit()),
            "refs/for/master/" + name("topic1"));

    approve(h.getChangeId());
    approve(i.getChangeId());
    submit(i.getChangeId());

    approve(e.getChangeId());
    approve(f.getChangeId());
    approve(g.getChangeId());
    approve(j.getChangeId());
    approve(k.getChangeId());

    assertChangeSetMergeable(g.getChange(), false);
    assertChangeSetMergeable(k.getChange(), false);

    PushOneCommit.Result l =
        createChange(
            project1,
            "L",
            "new.txt",
            "Resolving conflicts again",
            ImmutableList.of(c.getCommit(), g.getCommit()),
            "refs/for/master/" + name("topic1"));

    approve(l.getChangeId());
    assertChangeSetMergeable(l.getChange(), true);

    submit(l.getChangeId());
    assertMerged(c.getChangeId());
    assertMerged(g.getChangeId());
    assertMerged(k.getChangeId());
  }

  @Test
  public void resolvingMergeCommitAtEndOfChainAndNotUpToDate() throws Exception {
    /*
        A <-- B
         \
          C  <- D
           \   /
             E

        B is the target branch, and D should be merged with B, but one
        of C conflicts with B
    */

    PushOneCommit.Result a = createChange("A");
    PushOneCommit.Result b =
        createChange("B", "new.txt", "No conflict line", ImmutableList.of(a.getCommit()));

    approve(a.getChangeId());
    approve(b.getChangeId());
    submit(b.getChangeId());

    PushOneCommit.Result c =
        createChange("C", "new.txt", "Create conflicts", ImmutableList.of(a.getCommit()));
    PushOneCommit.Result e = createChange("E", ImmutableList.of(c.getCommit()));
    PushOneCommit.Result d =
        createChange(
            "D", "new.txt", "Resolves conflicts", ImmutableList.of(c.getCommit(), e.getCommit()));

    approve(c.getChangeId());
    approve(e.getChangeId());
    approve(d.getChangeId());
    assertNotMergeable(d.getChange());
    assertChangeSetMergeable(d.getChange(), false);
  }

  private void submit(String changeId) throws Exception {
    gApi.changes().id(changeId).current().submit();
  }

  private void assertChangeSetMergeable(ChangeData change, boolean expected)
      throws MissingObjectException, IncorrectObjectTypeException, IOException,
          PermissionBackendException {
    ChangeSet cs = mergeSuperSet.get().completeChangeSet(change.change(), user(admin));
    assertThat(submit.unmergeableChanges(cs).isEmpty()).isEqualTo(expected);
  }

  private void assertMergeable(ChangeData change) throws Exception {
    change.setMergeable(null);
    assertThat(change.isMergeable()).isTrue();
  }

  private void assertNotMergeable(ChangeData change) throws Exception {
    change.setMergeable(null);
    assertThat(change.isMergeable()).isFalse();
  }

  private void assertMerged(String changeId) throws Exception {
    assertThat(gApi.changes().id(changeId).get().status).isEqualTo(ChangeStatus.MERGED);
  }

  private PushOneCommit.Result createChange(
      TestRepository<?> repo,
      String subject,
      String fileName,
      String content,
      List<RevCommit> parents,
      String ref)
      throws Exception {
    PushOneCommit push = pushFactory.create(admin.newIdent(), repo, subject, fileName, content);

    if (!parents.isEmpty()) {
      push.setParents(parents);
    }

    PushOneCommit.Result result;
    if (fileName.isEmpty()) {
      result = push.execute(ref);
    } else {
      result = push.to(ref);
    }
    result.assertOkStatus();
    return result;
  }

  private PushOneCommit.Result createChange(TestRepository<?> repo, String subject)
      throws Exception {
    return createChange(repo, subject, "x", "x", new ArrayList<>(), "refs/for/master");
  }

  private PushOneCommit.Result createChange(
      TestRepository<?> repo,
      String subject,
      String fileName,
      String content,
      List<RevCommit> parents)
      throws Exception {
    return createChange(repo, subject, fileName, content, parents, "refs/for/master");
  }

  @Override
  protected PushOneCommit.Result createChange(String subject) throws Exception {
    return createChange(testRepo, subject, "", "", Collections.emptyList(), "refs/for/master");
  }

  private PushOneCommit.Result createChange(String subject, List<RevCommit> parents)
      throws Exception {
    return createChange(testRepo, subject, "", "", parents, "refs/for/master");
  }

  private PushOneCommit.Result createChange(
      String subject, String fileName, String content, List<RevCommit> parents) throws Exception {
    return createChange(testRepo, subject, fileName, content, parents, "refs/for/master");
  }
}
