// Copyright (C) 2017 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.googlesource.gerrit.plugins.automerger;

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

import com.google.common.base.Charsets;
import com.google.common.io.CharStreams;
import com.google.gerrit.acceptance.GitUtil;
import com.google.gerrit.acceptance.LightweightPluginDaemonTest;
import com.google.gerrit.acceptance.PushOneCommit;
import com.google.gerrit.acceptance.TestPlugin;
import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.reviewdb.client.RefNames;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.config.AllProjectsName;
import com.google.gerrit.server.config.CanonicalWebUrl;
import com.google.gerrit.server.config.PluginConfigFactory;
import com.google.inject.Inject;
import com.google.inject.Provider;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.HashSet;
import java.util.Set;
import org.eclipse.jgit.errors.ConfigInvalidException;
import org.eclipse.jgit.internal.storage.dfs.InMemoryRepository;
import org.eclipse.jgit.junit.TestRepository;
import org.eclipse.jgit.lib.Config;
import org.junit.Test;

@TestPlugin(
    name = "automerger",
    sysModule = "com.googlesource.gerrit.plugins.automerger.AutomergerModule")
public class ConfigLoaderIT extends LightweightPluginDaemonTest {
  private ConfigLoader configLoader;
  @Inject private AllProjectsName allProjectsName;
  @Inject private PluginConfigFactory cfgFactory;
  @Inject @CanonicalWebUrl String canonicalGerritWebUrl;
  @Inject private Provider<CurrentUser> currentUser;
  private Project.NameKey manifestNameKey;

  @Test
  public void getProjectsInScopeTest_addProjects() throws Exception {
    defaultSetup("automerger.config");
    Set<String> expectedProjects = new HashSet<>();
    expectedProjects.add("platform/whee");
    expectedProjects.add("platform/added/project");
    assertThat(configLoader.getProjectsInScope("master", "ds_one")).isEqualTo(expectedProjects);
  }

  @Test
  public void getProjectsInScopeTest_setProjects() throws Exception {
    defaultSetup("automerger.config");
    Set<String> otherExpectedProjects = new HashSet<>();
    otherExpectedProjects.add("platform/some/project");
    otherExpectedProjects.add("platform/other/project");
    otherExpectedProjects.add("platform/added/project");
    assertThat(configLoader.getProjectsInScope("master", "ds_two"))
        .isEqualTo(otherExpectedProjects);
  }

  @Test
  public void getProjectsInScope_missingSourceManifest() throws Exception {
    createProject("All-Projects");
    manifestNameKey = createProject("platform/manifest");
    setupTestRepo("ds_one.xml", manifestNameKey, "ds_one", "default.xml");
    setupTestRepo("ds_two.xml", manifestNameKey, "ds_two", "default.xml");
    loadConfig("alternate.config");
    assertThat(configLoader.getProjectsInScope("master", "ds_one").isEmpty()).isTrue();
  }

  @Test
  public void getProjectsInScope_ignoreSourceManifest() throws Exception {
    defaultSetup("alternate.config");
    Set<String> expectedProjects = new HashSet<>();
    expectedProjects.add("platform/whee");
    expectedProjects.add("whuu");
    assertThat(configLoader.getProjectsInScope("master", "ds_two")).isEqualTo(expectedProjects);
  }

  @Test
  public void getProjectsInScope_ignoreSourceManifestWithMissingDestManifest() throws Exception {
    defaultSetup("alternate.config");
    assertThat(configLoader.getProjectsInScope("master", "ds_four").isEmpty()).isTrue();
  }

  @Test
  public void isSkipMergeTest_noSkip() throws Exception {
    defaultSetup("automerger.config");
    assertThat(configLoader.isSkipMerge("ds_two", "ds_three", "bla")).isFalse();
  }

  @Test
  public void isSkipMergeTest_blankMerge() throws Exception {
    defaultSetup("automerger.config");
    assertThat(configLoader.isSkipMerge("ds_two", "ds_three", "test test \n \n DO NOT MERGE lala"))
        .isTrue();
  }

  @Test
  public void isSkipMergeTest_blankMergeWithMergeAll() throws Exception {
    defaultSetup("automerger.config");
    assertThat(configLoader.isSkipMerge("master", "ds_two", "test test \n \n DO NOT MERGE"))
        .isFalse();
  }

  @Test
  public void isSkipMergeTest_alwaysBlankMerge() throws Exception {
    defaultSetup("automerger.config");
    assertThat(
            configLoader.isSkipMerge("master", "ds_one", "test test \n \n DO NOT MERGE ANYWHERE"))
        .isTrue();
  }

  @Test
  public void isSkipMergeTest_alwaysBlankMergeDummy() throws Exception {
    defaultSetup("alternate.config");
    assertThat(configLoader.isSkipMerge("master", "ds_two", "test test")).isFalse();
  }

  @Test
  public void isSkipMergeTest_alwaysBlankMergeNull() throws Exception {
    defaultSetup("alternate.config");
    assertThat(configLoader.isSkipMerge("master", "ds_two", "test test \n \n BLANK ANYWHERE"))
        .isTrue();
  }

  @Test
  public void isSkipMergeTest_noBlankMergeSpecified() throws Exception {
    defaultSetup("empty_blank.config");
    assertThat(configLoader.isSkipMerge("master", "ds_one", "test test \n \n DO NOT MERGE"))
        .isFalse();
  }

  @Test
  public void upstreamBranchesTest() throws Exception {
    defaultSetup("automerger.config");
    Set<String> expectedBranches = new HashSet<>();
    expectedBranches.add("master");
    assertThat(configLoader.getUpstreamBranches("ds_two", "platform/some/project"))
        .isEqualTo(expectedBranches);
  }

  @Test
  public void upstreamBranchesTest_nonexistentBranch() throws Exception {
    defaultSetup("automerger.config");
    Set<String> expectedBranches = new HashSet<>();
    assertThat(configLoader.getUpstreamBranches("master", "platform/some/project"))
        .isEqualTo(expectedBranches);
  }

  @Test
  public void downstreamBranchesTest() throws Exception {
    defaultSetup("automerger.config");
    Set<String> expectedBranches = new HashSet<>();
    expectedBranches.add("ds_two");
    assertThat(configLoader.getDownstreamBranches("master", "platform/some/project"))
        .isEqualTo(expectedBranches);
  }

  @Test
  public void downstreamBranchesTest_nonexistentBranch() throws Exception {
    defaultSetup("automerger.config");
    Set<String> expectedBranches = new HashSet<>();
    assertThat(configLoader.getDownstreamBranches("idontexist", "platform/some/project"))
        .isEqualTo(expectedBranches);
  }

  @Test
  public void downstreamBranchesTest_configException() throws Exception {
    defaultSetup("wrong.config");

    exception.expect(ConfigInvalidException.class);
    exception.expectMessage("Automerger config branch pair malformed: master..ds_one");
    configLoader.getDownstreamBranches("master", "platform/some/project");
  }

  @Test
  public void getAllDownstreamBranchesTest() throws Exception {
    defaultSetup("automerger.config");
    Set<String> expectedBranches = new HashSet<>();
    expectedBranches.add("ds_two");
    expectedBranches.add("ds_three");
    assertThat(configLoader.getAllDownstreamBranches("master", "platform/some/project"))
        .isEqualTo(expectedBranches);
  }

  private void defaultSetup(String resourceName) throws Exception {
    createProject("All-Projects");
    manifestNameKey = createProject("platform/manifest");
    setupTestRepo("default.xml", manifestNameKey, "master", "default.xml");
    setupTestRepo("ds_one.xml", manifestNameKey, "ds_one", "default.xml");
    setupTestRepo("ds_two.xml", manifestNameKey, "ds_two", "default.xml");
    loadConfig(resourceName);
  }

  @Test
  public void getDefaultConflictMessageTest() throws Exception {
    defaultSetup("automerger.config");
    assertThat(configLoader.getConflictMessage()).isEqualTo("Merge conflict found on ${branch}");
  }

  @Test
  public void getMultilineConflictMessageTest() throws Exception {
    defaultSetup("alternate.config");
    assertThat(configLoader.getConflictMessage())
        .isEqualTo("line1\n" + "line2\n" + "line3 ${branch}\n" + "line4");
  }

  @Test
  public void getDefaultManifestConflictMessageTest() throws Exception {
    defaultSetup("automerger.config");
    assertThat(configLoader.getManifestConflictMessage())
        .isEqualTo("Merge conflict found on ${branch}");
  }

  @Test
  public void getMultilineManifestConflictMessageTest() throws Exception {
    defaultSetup("alternate.config");
    assertThat(configLoader.getManifestConflictMessage())
        .isEqualTo("mline1\n" + "mline2\n" + "mline3 ${branch}\n" + "mline4");
  }

  @Test
  public void getMinAutomergeVoteTest() throws Exception {
    defaultSetup("alternate.config");
    assertThat(configLoader.getMinAutomergeVote()).isEqualTo(-3);
  }

  @Test
  public void minAutomergeVoteDisabledTest() throws Exception {
    defaultSetup("automerger.config");
    assertThat(configLoader.minAutomergeVoteDisabled()).isFalse();
  }

  @Test
  public void getContextUserIdTest() throws Exception {
    defaultSetup("context_user.config");
    assertThat(configLoader.getContextUserId()).isEqualTo(new Account.Id(102304));
  }

  @Test
  public void getContextUserIdTest_noContextUser() throws Exception {
    defaultSetup("automerger.config");
    assertThat(configLoader.getContextUserId()).isEqualTo(currentUser.get().getAccountId());
  }

  private void setupTestRepo(
      String resourceName, Project.NameKey projectNameKey, String branchName, String filename)
      throws Exception {
    TestRepository<InMemoryRepository> repo = cloneProject(projectNameKey, admin);
    try (InputStream in = getClass().getResourceAsStream(resourceName)) {
      String resourceString = CharStreams.toString(new InputStreamReader(in, Charsets.UTF_8));

      PushOneCommit push =
          pushFactory.create(db, admin.getIdent(), repo, "some subject", filename, resourceString);
      push.to("refs/heads/" + branchName).assertOkStatus();
    }
  }

  private void pushConfig(String resourceName) throws Exception {
    TestRepository<InMemoryRepository> allProjectRepo = cloneProject(allProjects, admin);
    GitUtil.fetch(allProjectRepo, RefNames.REFS_CONFIG + ":config");
    allProjectRepo.reset("config");
    try (InputStream in = getClass().getResourceAsStream(resourceName)) {
      String resourceString = CharStreams.toString(new InputStreamReader(in, Charsets.UTF_8));

      Config cfg = new Config();
      cfg.fromText(resourceString);
      // Update manifest project path to the result of createProject(resourceName), since it is
      // scoped to the test method
      cfg.setString("global", null, "manifestProject", manifestNameKey.get());
      PushOneCommit push =
          pushFactory.create(
              db, admin.getIdent(), allProjectRepo, "Subject", "automerger.config", cfg.toText());
      push.to("refs/meta/config").assertOkStatus();
    }
  }

  private void loadConfig(String configFilename) throws Exception {
    pushConfig(configFilename);
    configLoader =
        new ConfigLoader(
            gApi, allProjectsName, "automerger", canonicalGerritWebUrl, cfgFactory, currentUser);
  }
}
