/*
 * Copyright 2017 Cisco Systems, Inc.
 *
 * 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.cisco.gerrit.plugins.slack.message;

import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.core.Is.is;
import static org.junit.Assert.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

import com.cisco.gerrit.plugins.slack.config.ProjectConfig;
import com.google.common.base.Suppliers;
import com.google.gerrit.extensions.client.ChangeKind;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.server.config.PluginConfig;
import com.google.gerrit.server.config.PluginConfigFactory;
import com.google.gerrit.server.data.AccountAttribute;
import com.google.gerrit.server.data.ChangeAttribute;
import com.google.gerrit.server.data.PatchSetAttribute;
import com.google.gerrit.server.events.PatchSetCreatedEvent;
import org.junit.Test;

/** Tests for the PatchSetCreatedMessageGeneratorTest class. */
public class PatchSetCreatedMessageGeneratorTest {
  private static final String PROJECT_NAME = "test-project";

  private Project.NameKey mockNameKey = mock(Project.NameKey.class);

  private PluginConfigFactory mockConfigFactory = mock(PluginConfigFactory.class);

  private PluginConfig mockPluginConfig = mock(PluginConfig.class);

  private PatchSetCreatedEvent mockEvent = mock(PatchSetCreatedEvent.class);
  private AccountAttribute mockAccount = mock(AccountAttribute.class);
  private ChangeAttribute mockChange = mock(ChangeAttribute.class);
  private PatchSetAttribute mockPatchSet = mock(PatchSetAttribute.class);

  private ProjectConfig getConfig(
      String ignore,
      boolean publishOnPatchSetCreated,
      boolean ignoreUnchangedPatchSet,
      boolean ignoreWorkInProgressPatchSet,
      boolean ignorePrivatePatchSet)
      throws Exception {
    Project.NameKey projectNameKey;
    projectNameKey = Project.NameKey.parse(PROJECT_NAME);

    // Setup mocks
    when(mockConfigFactory.getFromProjectConfigWithInheritance(
            projectNameKey, ProjectConfig.CONFIG_NAME))
        .thenReturn(mockPluginConfig);

    when(mockConfigFactory.getFromGerritConfig(ProjectConfig.CONFIG_NAME))
        .thenReturn(mockPluginConfig);

    when(mockPluginConfig.getBoolean("enabled", false)).thenReturn(true);
    when(mockPluginConfig.getString("webhookurl", "")).thenReturn("https://webook/");
    when(mockPluginConfig.getString("channel", "general")).thenReturn("testchannel");
    when(mockPluginConfig.getString("username", "gerrit")).thenReturn("testuser");
    when(mockPluginConfig.getString("ignore", "")).thenReturn(ignore);
    when(mockPluginConfig.getBoolean("publish-on-patch-set-created", true))
        .thenReturn(publishOnPatchSetCreated);
    when(mockPluginConfig.getBoolean("ignore-unchanged-patch-set", true))
        .thenReturn(ignoreUnchangedPatchSet);
    when(mockPluginConfig.getBoolean("ignore-wip-patch-set", true))
        .thenReturn(ignoreWorkInProgressPatchSet);
    when(mockPluginConfig.getBoolean("ignore-private-patch-set", true))
        .thenReturn(ignorePrivatePatchSet);

    return new ProjectConfig(mockConfigFactory, PROJECT_NAME);
  }

  private ProjectConfig getConfig(String ignore) throws Exception {
    return getConfig(
        ignore,
        true /* publishOnPatchSetCreated */,
        true /* ignoreUnchangedPatchSet */,
        true /* ignoreWorkInProgressPatchSet */,
        true /* ignorePrivatePatchSet */);
  }

  private ProjectConfig getConfig(boolean publishOnPatchSetCreated) throws Exception {
    return getConfig(
        "^WIP.*",
        publishOnPatchSetCreated,
        true /* ignoreUnchangedPatchSet */,
        true /* ignoreWorkInProgressPatchSet */,
        true /* ignorePrivatePatchSet */);
  }

  private ProjectConfig getConfig(boolean publishOnPatchSetCreated, boolean ignoreUnchangedPatchSet)
      throws Exception {
    return getConfig(
        "^WIP.*",
        publishOnPatchSetCreated,
        ignoreUnchangedPatchSet,
        true /* ignoreWorkInProgressPatchSet */,
        true /* ignorePrivatePatchSet */);
  }

  private ProjectConfig getConfig(
      boolean publishOnPatchSetCreated,
      boolean ignoreUnchangedPatchSet,
      boolean ignoreWorkInProgressPatchSet,
      boolean ignorePrivatePatchSet)
      throws Exception {
    return getConfig(
        "^WIP.*",
        publishOnPatchSetCreated,
        ignoreUnchangedPatchSet,
        ignoreWorkInProgressPatchSet,
        ignorePrivatePatchSet);
  }

  private ProjectConfig getConfig() throws Exception {
    return getConfig(
        "^WIP.*",
        true /* publishOnPatchSetCreated */,
        true /* ignoreUnchangedPatchSet */,
        true /* ignoreWorkInProgressPatchSet */,
        true /* ignorePrivatePatchSet */);
  }

  @Test
  public void factoryCreatesExpectedType() throws Exception {
    ProjectConfig config = getConfig();
    MessageGenerator messageGenerator;
    messageGenerator = MessageGeneratorFactory.newInstance(mockEvent, config);

    assertThat(messageGenerator instanceof PatchSetCreatedMessageGenerator, is(true));
  }

  @Test
  public void publishesWhenExpected() throws Exception {
    // Setup mocks
    ProjectConfig config = getConfig();
    mockEvent.change = Suppliers.ofInstance(mockChange);
    mockChange.commitMessage = "This is a title\nAnd a the body.";

    // Test
    MessageGenerator messageGenerator;
    messageGenerator = MessageGeneratorFactory.newInstance(mockEvent, config);

    assertThat(messageGenerator.shouldPublish(), is(true));
  }

  @Test
  public void doesNotPublishWhenMessageMatchesIgnore() throws Exception {
    // Setup mocks
    ProjectConfig config = getConfig();
    mockEvent.change = Suppliers.ofInstance(mockChange);
    mockChange.commitMessage = "WIP-This is a title\nAnd a the body.";

    // Test
    MessageGenerator messageGenerator;
    messageGenerator = MessageGeneratorFactory.newInstance(mockEvent, config);

    assertThat(messageGenerator.shouldPublish(), is(false));
  }

  @Test
  public void doesNotPublishWhenTurnedOff() throws Exception {
    // Setup mocks
    ProjectConfig config = getConfig(false /* publishOnPatchSetCreated */);
    mockEvent.change = Suppliers.ofInstance(mockChange);
    mockChange.commitMessage = "This is a title\nAnd a the body.";

    // Test
    MessageGenerator messageGenerator;
    messageGenerator = MessageGeneratorFactory.newInstance(mockEvent, config);

    assertThat(messageGenerator.shouldPublish(), is(false));
  }

  @Test
  public void handlesInvalidIgnorePatterns() throws Exception {
    ProjectConfig config = getConfig(null /* ignore */);

    // Test
    MessageGenerator messageGenerator;
    messageGenerator = MessageGeneratorFactory.newInstance(mockEvent, config);

    assertThat(messageGenerator.shouldPublish(), is(true));
  }

  @Test
  public void doesNotPublishWhenTrivialRebase() throws Exception {
    // Setup mocks
    ProjectConfig config = getConfig();
    mockEvent.change = Suppliers.ofInstance(mockChange);
    mockEvent.patchSet = Suppliers.ofInstance(mockPatchSet);
    mockPatchSet.kind = ChangeKind.TRIVIAL_REBASE;

    // Test
    MessageGenerator messageGenerator;
    messageGenerator = MessageGeneratorFactory.newInstance(mockEvent, config);

    assertThat(messageGenerator.shouldPublish(), is(false));
  }

  @Test
  public void publishesWhenTrivialRebase() throws Exception {
    // Setup mocks
    ProjectConfig config = getConfig(true, false);
    mockEvent.change = Suppliers.ofInstance(mockChange);
    mockEvent.patchSet = Suppliers.ofInstance(mockPatchSet);
    mockPatchSet.kind = ChangeKind.TRIVIAL_REBASE;

    // Test
    MessageGenerator messageGenerator;
    messageGenerator = MessageGeneratorFactory.newInstance(mockEvent, config);

    assertThat(messageGenerator.shouldPublish(), is(true));
  }

  @Test
  public void doesNotPublishWhenMergeUpdate() throws Exception {
    // Setup mocks
    ProjectConfig config = getConfig();
    mockEvent.change = Suppliers.ofInstance(mockChange);
    mockEvent.patchSet = Suppliers.ofInstance(mockPatchSet);
    mockPatchSet.kind = ChangeKind.MERGE_FIRST_PARENT_UPDATE;

    // Test
    MessageGenerator messageGenerator;
    messageGenerator = MessageGeneratorFactory.newInstance(mockEvent, config);

    assertThat(messageGenerator.shouldPublish(), is(false));
  }

  @Test
  public void publishesWhenMergeUpdate() throws Exception {
    // Setup mocks
    ProjectConfig config = getConfig(true, false);
    mockEvent.change = Suppliers.ofInstance(mockChange);
    mockEvent.patchSet = Suppliers.ofInstance(mockPatchSet);
    mockPatchSet.kind = ChangeKind.MERGE_FIRST_PARENT_UPDATE;

    // Test
    MessageGenerator messageGenerator;
    messageGenerator = MessageGeneratorFactory.newInstance(mockEvent, config);

    assertThat(messageGenerator.shouldPublish(), is(true));
  }

  @Test
  public void doesNotPublishWhenNoCodeChange() throws Exception {
    // Setup mocks
    ProjectConfig config = getConfig();
    mockEvent.change = Suppliers.ofInstance(mockChange);
    mockEvent.patchSet = Suppliers.ofInstance(mockPatchSet);
    mockPatchSet.kind = ChangeKind.NO_CODE_CHANGE;

    // Test
    MessageGenerator messageGenerator;
    messageGenerator = MessageGeneratorFactory.newInstance(mockEvent, config);

    assertThat(messageGenerator.shouldPublish(), is(false));
  }

  @Test
  public void publishesWhenNoCodeChange() throws Exception {
    // Setup mocks
    ProjectConfig config = getConfig(true, false);
    mockEvent.change = Suppliers.ofInstance(mockChange);
    mockEvent.patchSet = Suppliers.ofInstance(mockPatchSet);
    mockPatchSet.kind = ChangeKind.NO_CODE_CHANGE;

    // Test
    MessageGenerator messageGenerator;
    messageGenerator = MessageGeneratorFactory.newInstance(mockEvent, config);

    assertThat(messageGenerator.shouldPublish(), is(true));
  }

  @Test
  public void doesNotPublishWhenNoChange() throws Exception {
    // Setup mocks
    ProjectConfig config = getConfig();
    mockEvent.change = Suppliers.ofInstance(mockChange);
    mockEvent.patchSet = Suppliers.ofInstance(mockPatchSet);
    mockPatchSet.kind = ChangeKind.NO_CHANGE;

    // Test
    MessageGenerator messageGenerator;
    messageGenerator = MessageGeneratorFactory.newInstance(mockEvent, config);

    assertThat(messageGenerator.shouldPublish(), is(false));
  }

  @Test
  public void publishesWhenNoChange() throws Exception {
    // Setup mocks
    ProjectConfig config = getConfig(true, false);
    mockEvent.change = Suppliers.ofInstance(mockChange);
    mockEvent.patchSet = Suppliers.ofInstance(mockPatchSet);
    mockPatchSet.kind = ChangeKind.NO_CHANGE;

    // Test
    MessageGenerator messageGenerator;
    messageGenerator = MessageGeneratorFactory.newInstance(mockEvent, config);

    assertThat(messageGenerator.shouldPublish(), is(true));
  }

  @Test
  public void publishesWhenRework() throws Exception {
    // Setup mocks
    ProjectConfig config = getConfig();
    mockEvent.change = Suppliers.ofInstance(mockChange);
    mockEvent.patchSet = Suppliers.ofInstance(mockPatchSet);
    mockPatchSet.kind = ChangeKind.REWORK;

    // Test
    MessageGenerator messageGenerator;
    messageGenerator = MessageGeneratorFactory.newInstance(mockEvent, config);

    assertThat(messageGenerator.shouldPublish(), is(true));
  }

  @Test
  public void doesNotPublishWhenWorkInProgress() throws Exception {
    // Setup mocks
    ProjectConfig config = getConfig();
    mockEvent.change = Suppliers.ofInstance(mockChange);
    mockChange.wip = true;

    // Test
    MessageGenerator messageGenerator;
    messageGenerator = MessageGeneratorFactory.newInstance(mockEvent, config);

    assertThat(messageGenerator.shouldPublish(), is(false));
  }

  @Test
  public void doesNotPublishWhenPrivate() throws Exception {
    // Setup mocks
    ProjectConfig config = getConfig();
    mockEvent.change = Suppliers.ofInstance(mockChange);
    mockChange.isPrivate = true;

    // Test
    MessageGenerator messageGenerator;
    messageGenerator = MessageGeneratorFactory.newInstance(mockEvent, config);

    assertThat(messageGenerator.shouldPublish(), is(false));
  }

  @Test
  public void publishesWhenWorkInProgress() throws Exception {
    // Setup mocks
    ProjectConfig config =
        getConfig(
            true /* publishOnPatchSetCreated */,
            false /* ignoreRebaseEmptyPatchSet */,
            false /* ignoreWorkInProgressPatchSet */,
            false /* ignorePrivatePatchSet */);
    mockEvent.change = Suppliers.ofInstance(mockChange);
    mockChange.wip = true;

    // Test
    MessageGenerator messageGenerator;
    messageGenerator = MessageGeneratorFactory.newInstance(mockEvent, config);

    assertThat(messageGenerator.shouldPublish(), is(true));
  }

  @Test
  public void publishesWhenPrivate() throws Exception {
    // Setup mocks
    ProjectConfig config =
        getConfig(
            true /* publishOnPatchSetCreated */,
            false /* ignoreRebaseEmptyPatchSet */,
            false /* ignoreWorkInProgressPatchSet */,
            false /* ignorePrivatePatchSet */);
    mockEvent.change = Suppliers.ofInstance(mockChange);
    mockChange.isPrivate = true;

    // Test
    MessageGenerator messageGenerator;
    messageGenerator = MessageGeneratorFactory.newInstance(mockEvent, config);

    assertThat(messageGenerator.shouldPublish(), is(true));
  }

  @Test
  public void generatesExpectedMessage() throws Exception {
    // Setup mocks
    ProjectConfig config = getConfig();
    mockEvent.change = Suppliers.ofInstance(mockChange);
    mockEvent.uploader = Suppliers.ofInstance(mockAccount);

    mockChange.number = 1234;
    mockChange.project = "testproject";
    mockChange.branch = "master";
    mockChange.url = "https://change/";
    mockChange.commitMessage = "This is the title\nThis is the message body.";

    mockAccount.name = "Unit Tester";

    // Test
    MessageGenerator messageGenerator;
    messageGenerator = MessageGeneratorFactory.newInstance(mockEvent, config);

    String expectedResult;
    expectedResult =
        "{\n"
            + "  \"channel\": \"#testchannel\",\n"
            + "  \"attachments\": [\n"
            + "    {\n"
            + "      \"fallback\": \"Unit Tester proposed testproject (master) https://change/: This is the title\",\n"
            + "      \"pretext\": \"Unit Tester proposed <https://change/|testproject (master) change 1234>\",\n"
            + "      \"title\": \"This is the title\",\n"
            + "      \"title_link\": \"https://change/\",\n"
            + "      \"text\": \"\",\n"
            + "      \"color\": \"good\"\n"
            + "    }\n"
            + "  ]\n"
            + "}\n";

    String actualResult;
    actualResult = messageGenerator.generate();

    assertThat(actualResult, is(equalTo(expectedResult)));
  }
}
