/*
 * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
 * agreements. See the NOTICE file distributed with this work for additional information regarding
 * copyright ownership. The ASF licenses this file to You 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 org.apache.geode.management.internal.cli.commands;

import static org.assertj.core.api.Assertions.assertThat;

import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.junit.rules.TemporaryFolder;
import org.junit.rules.TestName;

import org.apache.geode.cache.configuration.CacheConfig;
import org.apache.geode.cache.configuration.CacheElement;
import org.apache.geode.cache.configuration.RegionConfig;
import org.apache.geode.distributed.internal.InternalLocator;
import org.apache.geode.test.dunit.IgnoredException;
import org.apache.geode.test.dunit.rules.ClusterStartupRule;
import org.apache.geode.test.dunit.rules.MemberVM;
import org.apache.geode.test.junit.categories.WanTest;
import org.apache.geode.test.junit.rules.GfshCommandRule;
import org.apache.geode.test.junit.rules.serializable.SerializableTestName;

@Category(WanTest.class)
public class AlterRegionCommandDUnitTest {
  private static MemberVM locator;

  @Rule
  public GfshCommandRule gfsh = new GfshCommandRule();

  @Rule
  public TestName testName = new SerializableTestName();

  @Rule
  public ClusterStartupRule lsRule = new ClusterStartupRule();

  @Rule
  public TemporaryFolder temporaryFolder = new TemporaryFolder();

  @Before
  public void before() throws Exception {
    locator = lsRule.startLocatorVM(0);
    lsRule.startServerVM(1, locator.getPort());

    gfsh.connectAndVerify(locator);
    gfsh.executeAndAssertThat(
        "create disk-store --name=diskStore --dir=" + temporaryFolder.getRoot())
        .statusIsSuccess()
        .doesNotContainOutput("Did not complete waiting");
  }

  @Test
  public void alterPartitionRegionWithParallelAsynchronousEventQueueShouldPersistTheChangesIntoTheClusterConfigurationService() {
    String regionName = testName.getMethodName();
    String asyncEventQueueName = "asyncEventQueue1";

    gfsh.executeAndAssertThat(
        "create async-event-queue --parallel=true --persistent=false --listener=org.apache.geode.internal.cache.wan.MyAsyncEventListener --id="
            + asyncEventQueueName)
        .statusIsSuccess();
    locator.waitUntilAsyncEventQueuesAreReadyOnExactlyThisManyServers(asyncEventQueueName, 1);

    gfsh.executeAndAssertThat("create region --type=PARTITION --name=" + regionName)
        .statusIsSuccess();
    locator.waitUntilRegionIsReadyOnExactlyThisManyServers("/" + regionName, 1);

    // Associate the async-event-queue
    gfsh.executeAndAssertThat(
        "alter region --name=" + regionName + " --async-event-queue-id=" + asyncEventQueueName)
        .statusIsSuccess().containsOutput("server-1", "OK", "Region " + regionName + " altered");

    // Check the cluster configuration service.
    locator.invoke(() -> {
      InternalLocator internalLocator = ClusterStartupRule.getLocator();
      assertThat(internalLocator).isNotNull();
      CacheConfig config =
          internalLocator.getConfigurationPersistenceService().getCacheConfig("cluster");

      RegionConfig regionConfig = CacheElement.findElement(config.getRegions(), regionName);
      assertThat(regionConfig).isNotNull();
      assertThat(regionConfig.getRegionAttributes()).isNotNull();
      assertThat(regionConfig.getRegionAttributes().getAsyncEventQueueIds()).isNotEmpty()
          .isEqualTo(asyncEventQueueName);
    });
  }

  @Test
  public void alterNonColocatedPartitionRegionWithTheSameParallelAsynchronousEventQueueShouldThrowExceptionAndPreventTheClusterConfigurationServiceFromBeingUpdated() {
    IgnoredException.addIgnoredException(
        "Non colocated regions (.*) cannot have the same parallel async event queue id (.*) configured.");

    String asyncEventQueue = "asyncEventQueue";
    String region1Name = testName.getMethodName() + "1";
    String region2Name = testName.getMethodName() + "2";

    gfsh.executeAndAssertThat(
        "create async-event-queue --parallel=true --persistent=false --listener=org.apache.geode.internal.cache.wan.MyAsyncEventListener --id="
            + asyncEventQueue)
        .statusIsSuccess();
    locator.waitUntilAsyncEventQueuesAreReadyOnExactlyThisManyServers(asyncEventQueue, 1);

    gfsh.executeAndAssertThat("create region --type=PARTITION --name=" + region1Name)
        .statusIsSuccess();
    locator.waitUntilRegionIsReadyOnExactlyThisManyServers("/" + region1Name, 1);

    gfsh.executeAndAssertThat("create region --type=PARTITION --name=" + region2Name)
        .statusIsSuccess();
    locator.waitUntilRegionIsReadyOnExactlyThisManyServers("/" + region2Name, 1);

    // Associate the async-event-queue to both regions (second one should fail because they are not
    // co-located)
    gfsh.executeAndAssertThat(
        "alter region --name=" + region1Name + " --async-event-queue-id=" + asyncEventQueue)
        .statusIsSuccess().containsOutput("server-1", "OK", "Region " + region1Name + " altered");
    gfsh.executeAndAssertThat(
        "alter region --name=" + region2Name + " --async-event-queue-id=" + asyncEventQueue)
        .statusIsError().containsOutput("server-1", "ERROR",
            "Non colocated regions /" + region2Name + ", /" + region1Name
                + " cannot have the same parallel async event queue id " + asyncEventQueue
                + " configured.");

    // The exception must be thrown early in the initialization, so the change shouldn't be
    // persisted to the cluster configuration service for the second region.
    locator.invoke(() -> {
      InternalLocator internalLocator = ClusterStartupRule.getLocator();
      assertThat(internalLocator).isNotNull();
      CacheConfig config =
          internalLocator.getConfigurationPersistenceService().getCacheConfig("cluster");

      RegionConfig regionConfig = CacheElement.findElement(config.getRegions(), region1Name);
      assertThat(regionConfig).isNotNull();
      assertThat(regionConfig.getRegionAttributes()).isNotNull();
      assertThat(regionConfig.getRegionAttributes().getAsyncEventQueueIds())
          .isEqualTo(asyncEventQueue);

      RegionConfig region2Config = CacheElement.findElement(config.getRegions(), region2Name);
      assertThat(region2Config).isNotNull();
      assertThat(region2Config.getRegionAttributes()).isNotNull();
      assertThat(region2Config.getRegionAttributes().getAsyncEventQueueIds()).isBlank();
    });
  }

  @Test
  public void alterPartitionPersistentRegionWithParallelNonPersistentAsynchronousEventQueueShouldThrowExceptionAndPreventTheClusterConfigurationServiceFromBeingUpdated() {
    IgnoredException.addIgnoredException(
        "Non persistent asynchronous event queue (.*) can not be attached to persistent region (.*)");
    String regionName = testName.getMethodName();
    String asyncEventQueueName = "asyncEventQueue";

    gfsh.executeAndAssertThat(
        "create async-event-queue --parallel=true --persistent=false --listener=org.apache.geode.internal.cache.wan.MyAsyncEventListener --id="
            + asyncEventQueueName)
        .statusIsSuccess();
    locator.waitUntilAsyncEventQueuesAreReadyOnExactlyThisManyServers(asyncEventQueueName, 1);

    gfsh.executeAndAssertThat("create region --type=PARTITION_PERSISTENT --name=" + regionName
        + " --disk-store=diskStore").statusIsSuccess();
    locator.waitUntilRegionIsReadyOnExactlyThisManyServers("/" + regionName, 1);

    // Make sure that the next invocations also fail and that the changes are not persisted to the
    // cluster configuration service. See GEODE-6551.
    gfsh.executeAndAssertThat(
        "alter region --name=" + regionName + " --async-event-queue-id=" + asyncEventQueueName)
        .statusIsError()
        .containsOutput("server-1", "ERROR", "Non persistent asynchronous event queue "
            + asyncEventQueueName + " can not be attached to persistent region /" + regionName);
    gfsh.executeAndAssertThat(
        "alter region --name=" + regionName + " --async-event-queue-id=" + asyncEventQueueName)
        .statusIsError()
        .containsOutput("server-1", "ERROR", "Non persistent asynchronous event queue "
            + asyncEventQueueName + " can not be attached to persistent region /" + regionName);
    gfsh.executeAndAssertThat(
        "alter region --name=" + regionName + " --async-event-queue-id=" + asyncEventQueueName)
        .statusIsError()
        .containsOutput("server-1", "ERROR", "Non persistent asynchronous event queue "
            + asyncEventQueueName + " can not be attached to persistent region /" + regionName);

    // The exception must be thrown early in the initialization, so the change shouldn't be
    // persisted to the cluster configuration service.
    locator.invoke(() -> {
      InternalLocator internalLocator = ClusterStartupRule.getLocator();
      assertThat(internalLocator).isNotNull();
      CacheConfig config =
          internalLocator.getConfigurationPersistenceService().getCacheConfig("cluster");

      RegionConfig regionConfig = CacheElement.findElement(config.getRegions(), regionName);
      assertThat(regionConfig).isNotNull();
      assertThat(regionConfig.getRegionAttributes()).isNotNull();
      assertThat(regionConfig.getRegionAttributes().getAsyncEventQueueIds()).isBlank();
    });
  }

  @Test
  public void alterPartitionRegionWithParallelGatewaySenderShouldPersistTheChangesIntoTheClusterConfigurationService() {
    IgnoredException.addIgnoredException("could not get remote locator information");
    String regionName = testName.getMethodName();
    String gatewaySenderName = "gatewaySender";

    gfsh.executeAndAssertThat(
        "create gateway-sender --parallel=true --enable-persistence=false --remote-distributed-system-id=2 --id="
            + gatewaySenderName)
        .statusIsSuccess()
        .doesNotContainOutput("Did not complete waiting");

    gfsh.executeAndAssertThat("create region --type=PARTITION --name=" + regionName)
        .statusIsSuccess();
    locator.waitUntilRegionIsReadyOnExactlyThisManyServers("/" + regionName, 1);

    // Associate the gateway-sender
    gfsh.executeAndAssertThat(
        "alter region --name=" + regionName + " --gateway-sender-id=" + gatewaySenderName)
        .statusIsSuccess().containsOutput("server-1", "OK", "Region " + regionName + " altered");

    // Check the cluster configuration service.
    locator.invoke(() -> {
      InternalLocator internalLocator = ClusterStartupRule.getLocator();
      assertThat(internalLocator).isNotNull();
      CacheConfig config =
          internalLocator.getConfigurationPersistenceService().getCacheConfig("cluster");

      RegionConfig regionConfig = CacheElement.findElement(config.getRegions(), regionName);
      assertThat(regionConfig).isNotNull();
      assertThat(regionConfig.getRegionAttributes()).isNotNull();
      assertThat(regionConfig.getRegionAttributes().getGatewaySenderIds()).isNotEmpty()
          .isEqualTo(gatewaySenderName);
    });
  }

  @Test
  public void alterNonColocatedPartitionRegionWithTheSameParallelGatewaySenderShouldThrowExceptionAndPreventTheClusterConfigurationServiceFromBeingUpdated() {
    IgnoredException.addIgnoredException("could not get remote locator information");
    IgnoredException.addIgnoredException(
        "Non colocated regions (.*) cannot have the same parallel gateway sender id (.*) configured.");

    String gatewaySenderName = "gatewaySender";
    String region1Name = testName.getMethodName() + "1";
    String region2Name = testName.getMethodName() + "2";

    gfsh.executeAndAssertThat(
        "create gateway-sender --parallel=true --enable-persistence=false --remote-distributed-system-id=2 --id="
            + gatewaySenderName)
        .statusIsSuccess()
        .doesNotContainOutput("Did not complete waiting");

    gfsh.executeAndAssertThat("create region --type=PARTITION --name=" + region1Name)
        .statusIsSuccess();
    locator.waitUntilRegionIsReadyOnExactlyThisManyServers("/" + region1Name, 1);

    gfsh.executeAndAssertThat("create region --type=PARTITION --name=" + region2Name)
        .statusIsSuccess();
    locator.waitUntilRegionIsReadyOnExactlyThisManyServers("/" + region2Name, 1);

    // Associate the gateway-sender to both regions (second one should fail because they are not
    // co-located)
    gfsh.executeAndAssertThat(
        "alter region --name=" + region1Name + " --gateway-sender-id=" + gatewaySenderName)
        .statusIsSuccess().containsOutput("server-1", "OK", "Region " + region1Name + " altered");
    gfsh.executeAndAssertThat(
        "alter region --name=" + region2Name + " --gateway-sender-id=" + gatewaySenderName)
        .statusIsError().containsOutput("server-1", "ERROR",
            "Non colocated regions /" + region2Name + ", /" + region1Name
                + " cannot have the same parallel gateway sender id " + gatewaySenderName
                + " configured.");

    // The exception must be thrown early in the initialization, so the change shouldn't be
    // persisted to the cluster configuration service for the second region.
    locator.invoke(() -> {
      InternalLocator internalLocator = ClusterStartupRule.getLocator();
      assertThat(internalLocator).isNotNull();
      CacheConfig config =
          internalLocator.getConfigurationPersistenceService().getCacheConfig("cluster");

      RegionConfig regionConfig = CacheElement.findElement(config.getRegions(), region1Name);
      assertThat(regionConfig).isNotNull();
      assertThat(regionConfig.getRegionAttributes()).isNotNull();
      assertThat(regionConfig.getRegionAttributes().getGatewaySenderIds())
          .isEqualTo(gatewaySenderName);

      RegionConfig region2Config = CacheElement.findElement(config.getRegions(), region2Name);
      assertThat(region2Config).isNotNull();
      assertThat(region2Config.getRegionAttributes()).isNotNull();
      assertThat(region2Config.getRegionAttributes().getGatewaySenderIds()).isBlank();
    });
  }

  @Test
  public void alterPartitionPersistentRegionWithParallelNonPersistentGatewaySenderShouldThrowExceptionAndPreventTheClusterConfigurationServiceFromBeingUpdated() {
    IgnoredException.addIgnoredException("could not get remote locator information");
    IgnoredException.addIgnoredException(
        "Non persistent gateway sender (.*) can not be attached to persistent region (.*)");
    String regionName = testName.getMethodName();
    String gatewaySenderName = "gatewaySender";

    gfsh.executeAndAssertThat(
        "create gateway-sender --parallel=true --enable-persistence=false --remote-distributed-system-id=2 --id="
            + gatewaySenderName)
        .statusIsSuccess()
        .doesNotContainOutput("Did not complete waiting");

    gfsh.executeAndAssertThat("create region --type=PARTITION_PERSISTENT --name=" + regionName
        + " --disk-store=diskStore").statusIsSuccess();
    locator.waitUntilRegionIsReadyOnExactlyThisManyServers("/" + regionName, 1);

    // Make sure that the next invocations also fail and that the changes are not persisted to the
    // cluster configuration service. See GEODE-6551.
    gfsh.executeAndAssertThat(
        "alter region --name=" + regionName + " --gateway-sender-id=" + gatewaySenderName)
        .statusIsError().containsOutput("server-1", "ERROR", "Non persistent gateway sender "
            + gatewaySenderName + " can not be attached to persistent region /" + regionName);
    gfsh.executeAndAssertThat(
        "alter region --name=" + regionName + " --gateway-sender-id=" + gatewaySenderName)
        .statusIsError().containsOutput("server-1", "ERROR", "Non persistent gateway sender "
            + gatewaySenderName + " can not be attached to persistent region /" + regionName);
    gfsh.executeAndAssertThat(
        "alter region --name=" + regionName + " --gateway-sender-id=" + gatewaySenderName)
        .statusIsError().containsOutput("server-1", "ERROR", "Non persistent gateway sender "
            + gatewaySenderName + " can not be attached to persistent region /" + regionName);

    // The exception must be thrown early in the initialization, so the change shouldn't be
    // persisted to the cluster configuration service.
    locator.invoke(() -> {
      InternalLocator internalLocator = ClusterStartupRule.getLocator();
      assertThat(internalLocator).isNotNull();
      CacheConfig config =
          internalLocator.getConfigurationPersistenceService().getCacheConfig("cluster");

      RegionConfig regionConfig = CacheElement.findElement(config.getRegions(), regionName);
      assertThat(regionConfig).isNotNull();
      assertThat(regionConfig.getRegionAttributes()).isNotNull();
      assertThat(regionConfig.getRegionAttributes().getGatewaySenderIds()).isBlank();
    });
  }
}
