/*
 * 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.apache.geode.cache.Region.SEPARATOR;
import static org.apache.geode.lang.Identifiable.find;
import static org.assertj.core.api.Assertions.assertThat;

import java.io.File;
import java.io.Serializable;
import java.net.URL;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

import org.apache.commons.io.FileUtils;
import org.junit.BeforeClass;
import org.junit.ClassRule;
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.Cache;
import org.apache.geode.cache.Declarable;
import org.apache.geode.cache.EntryOperation;
import org.apache.geode.cache.PartitionResolver;
import org.apache.geode.cache.Region;
import org.apache.geode.cache.RegionShortcut;
import org.apache.geode.cache.asyncqueue.AsyncEvent;
import org.apache.geode.cache.asyncqueue.AsyncEventListener;
import org.apache.geode.cache.configuration.CacheConfig;
import org.apache.geode.cache.configuration.RegionConfig;
import org.apache.geode.cache.util.CacheListenerAdapter;
import org.apache.geode.compression.Compressor;
import org.apache.geode.compression.SnappyCompressor;
import org.apache.geode.distributed.internal.InternalConfigurationPersistenceService;
import org.apache.geode.internal.cache.InternalRegion;
import org.apache.geode.internal.cache.PartitionedRegion;
import org.apache.geode.internal.cache.RegionEntryContext;
import org.apache.geode.test.compiler.JarBuilder;
import org.apache.geode.test.dunit.rules.ClusterStartupRule;
import org.apache.geode.test.dunit.rules.MemberVM;
import org.apache.geode.test.junit.categories.RegionsTest;
import org.apache.geode.test.junit.rules.GfshCommandRule;
import org.apache.geode.test.junit.rules.serializable.SerializableTestName;

@Category({RegionsTest.class})
public class CreateRegionCommandDUnitTest {

  private static MemberVM locator, server1, server2;

  public static class TestCacheListener<K, V> extends CacheListenerAdapter<K, V>
      implements Serializable {
  }

  public static class AnotherTestCacheListener<K, V> extends CacheListenerAdapter<K, V>
      implements Serializable {
  }

  public static class DummyAEQListener implements AsyncEventListener, Declarable {
    @Override
    @SuppressWarnings("rawtypes")
    public boolean processEvents(List<AsyncEvent> events) {
      return false;
    }
  }

  public static class DummyPartitionResolver<K, V> implements PartitionResolver<K, V>, Declarable {
    @Override
    public Object getRoutingObject(EntryOperation<K, V> opDetails) {
      return null;
    }

    @Override
    public String getName() {
      return "dummy";
    }
  }

  public static class DummyCompressor implements Compressor, Declarable {
    @Override
    public byte[] compress(byte[] input) {
      return new byte[0];
    }

    @Override
    public byte[] decompress(byte[] input) {
      return new byte[0];
    }
  }

  @ClassRule
  public static ClusterStartupRule lsRule = new ClusterStartupRule();

  @ClassRule
  public static GfshCommandRule gfsh = new GfshCommandRule();

  @Rule
  public TestName testName = new SerializableTestName();

  @Rule
  public TemporaryFolder tmpDir = new TemporaryFolder();

  @BeforeClass
  public static void before() throws Exception {
    locator = lsRule.startLocatorVM(0);
    server1 = lsRule.startServerVM(1, "group1", locator.getPort());
    server2 = lsRule.startServerVM(2, "group2", locator.getPort());

    gfsh.connectAndVerify(locator);
  }

  @Test
  public void multipleTemplateRegionTypes() {
    String regionName = testName.getMethodName();
    gfsh.executeAndAssertThat(
        "create region --name=" + regionName + " --type=REPLICATE --group=group1")
        .statusIsSuccess();
    gfsh.executeAndAssertThat(
        "create region --name=" + regionName + " --type=REPLICATE_PROXY --group=group2")
        .statusIsSuccess();

    gfsh.executeAndAssertThat("create region --name=failed --template-region=" + regionName)
        .statusIsError()
        .hasInfoSection().hasOutput()
        .contains("Multiple types of template region " + SEPARATOR
            + "multipleTemplateRegionTypes exist.");
  }

  @Test
  @SuppressWarnings("deprecation")
  public void testCreateRegionWithGoodCompressor() {
    String regionName = testName.getMethodName();
    gfsh.executeAndAssertThat("create region --name=" + regionName
        + " --type=REPLICATE --compressor=" + RegionEntryContext.DEFAULT_COMPRESSION_PROVIDER)
        .statusIsSuccess();

    server1.invoke(() -> {
      Cache cache = ClusterStartupRule.getCache();
      Region<?, ?> region = cache.getRegion(regionName);
      assertThat(region).isNotNull();
      assertThat(region.getAttributes().getCompressor())
          .isEqualTo(SnappyCompressor.getDefaultInstance());
    });

    gfsh.executeAndAssertThat("put --key='foo' --value='125' --region=" + regionName)
        .statusIsSuccess();
    gfsh.executeAndAssertThat("get --key='foo' --region=" + regionName)
        .statusIsSuccess()
        .containsKeyValuePair("Value", "\"125\"");
  }

  @Test
  public void testCreateRegionWithBadCompressor() {
    String regionName = testName.getMethodName();
    gfsh.executeAndAssertThat(
        "create region --name=" + regionName + " --type=REPLICATE --compressor=BAD_COMPRESSOR")
        .statusIsError();

    server1.invoke(() -> {
      Cache cache = ClusterStartupRule.getCache();
      Region<?, ?> region = cache.getRegion(regionName);
      assertThat(region).isNull();
    });
  }

  @Test
  public void testCreateRegionWithNoCompressor() {
    String regionName = testName.getMethodName();
    gfsh.executeAndAssertThat("create region --name=" + regionName + " --type=REPLICATE")
        .statusIsSuccess();

    server1.invoke(() -> {
      Cache cache = ClusterStartupRule.getCache();
      Region<?, ?> region = cache.getRegion(regionName);
      assertThat(region).isNotNull();
      assertThat(region.getAttributes().getCompressor()).isNull();
    });
  }

  @Test
  public void testCreateRegionWithSubregion() {
    String regionName = testName.getMethodName();
    gfsh.executeAndAssertThat("create region --name=" + regionName + " --type=REPLICATE")
        .statusIsSuccess();
    String subRegionName = "subregion";
    String subRegionPath = regionName + SEPARATOR + subRegionName;

    gfsh.executeAndAssertThat("create region --name=" + subRegionPath +
        " --type=REPLICATE")
        .statusIsSuccess();

    String subSubRegionName = "subregion2";
    String subSubRegionPath = regionName + SEPARATOR + subRegionName + SEPARATOR + subSubRegionName;
    gfsh.executeAndAssertThat("create region --name=" + subSubRegionPath +
        " --type=REPLICATE")
        .statusIsSuccess();

    server1.invoke(() -> {
      Cache cache = ClusterStartupRule.getCache();
      Region<?, ?> region = cache.getRegion(regionName);
      assertThat(region).isNotNull();

      Region<?, ?> subRegion = cache.getRegion(subRegionPath);
      assertThat(subRegion).isNotNull();

      Region<?, ?> subSubRegion = cache.getRegion(subSubRegionPath);
      assertThat(subSubRegion).isNotNull();
    });

    locator.invoke(() -> {
      CacheConfig config = ClusterStartupRule.getLocator().getConfigurationPersistenceService()
          .getCacheConfig("cluster");
      assertThat(find(config.getRegions(), regionName)).isNotNull();

      RegionConfig parentConfig = find(config.getRegions(), regionName);
      assertThat(find(parentConfig.getRegions(), subRegionName)).isNotNull();

      RegionConfig subRegionConfig = find(parentConfig.getRegions(),
          subRegionName);
      assertThat(find(subRegionConfig.getRegions(), subSubRegionName))
          .isNotNull();
    });
  }

  @Test
  public void testCreateRegionWithPartitionResolver() throws Exception {
    String regionName = testName.getMethodName();
    String PR_STRING = "package io.pivotal; "
        + "public class TestPartitionResolver implements org.apache.geode.cache.PartitionResolver { "
        + "   @Override" + "   public void close() {" + "   }" + "   @Override"
        + "   public Object getRoutingObject(org.apache.geode.cache.EntryOperation opDetails) { "
        + "    return null; " + "   }" + "   @Override" + "   public String getName() { "
        + "    return \"TestPartitionResolver\";" + "   }" + " }";
    final File prJarFile = new File(tmpDir.getRoot(), "myPartitionResolver.jar");
    new JarBuilder().buildJar(prJarFile, PR_STRING);

    gfsh.executeAndAssertThat("deploy --jar=" + prJarFile.getAbsolutePath()).statusIsSuccess();

    gfsh.executeAndAssertThat("create region --name=" + regionName
        + " --type=PARTITION --partition-resolver=io.pivotal.TestPartitionResolver")
        .statusIsSuccess();

    server1.invoke(() -> {
      Cache cache = ClusterStartupRule.getCache();
      PartitionedRegion region = (PartitionedRegion) cache.getRegion(regionName);
      PartitionResolver<?, ?> resolver = region.getPartitionAttributes().getPartitionResolver();
      assertThat(resolver).isNotNull();
      assertThat(resolver.getName()).isEqualTo("TestPartitionResolver");
    });
  }

  @Test
  public void testCreateRegionWithInvalidPartitionResolver() {
    gfsh.executeAndAssertThat("create region --name=" + testName.getMethodName()
        + " --type=PARTITION --partition-resolver=InvalidPartitionResolver")
        .statusIsError()
        .containsOutput("Error instantiating class");
  }

  @Test
  public void testCreateRegionWithInvalidCustomExpiry() {
    gfsh.executeAndAssertThat("create region --name=" + testName.getMethodName()
        + " --type=REPLICATE --entry-time-to-live-custom-expiry=InvalidCustomExpiry" +
        " --enable-statistics=true")
        .statusIsError()
        .containsOutput("Error instantiating class");

    gfsh.executeAndAssertThat("create region --name=" + testName.getMethodName()
        + " --type=REPLICATE --entry-idle-time-custom-expiry=InvalidCustomExpiry" +
        " --enable-statistics=true")
        .statusIsError()
        .containsOutput("Error instantiating class");
  }

  @Test
  public void testCreateRegionWithInvalidCacheLoader() {
    gfsh.executeAndAssertThat("create region --name=" + testName.getMethodName()
        + " --type=REPLICATE --cache-loader=InvalidCacheLoader")
        .statusIsError()
        .containsOutput("Error instantiating class");
  }

  @Test
  public void testCreateRegionWithInvalidCacheWriter() {
    gfsh.executeAndAssertThat("create region --name=" + testName.getMethodName()
        + " --type=REPLICATE --cache-writer=InvalidCacheWriter")
        .statusIsError()
        .containsOutput("Error instantiating class");
  }

  @Test
  public void testCreateRegionWithInvalidCacheListeners() {
    gfsh.executeAndAssertThat("create region --name=" + testName.getMethodName()
        + " --type=REPLICATE --cache-listener=" + TestCacheListener.class.getName()
        + ",InvalidCacheListener")
        .statusIsError()
        .containsOutput("Error instantiating class")
        .doesNotContainOutput("TestCacheListener");
  }

  @Test
  public void testCreateRegionForReplicatedRegionWithPartitionResolver() {
    String regionName = testName.getMethodName();
    gfsh.executeAndAssertThat("create region --name=" + regionName
        + " --type=REPLICATE --partition-resolver=InvalidPartitionResolver")
        .containsOutput("can be used only for creating a Partitioned Region").statusIsError();
  }

  @Test
  public void testCreateRegionFromTemplateFailsIfTemplateDoesNotExist() {
    gfsh.executeAndAssertThat(
        "create region --template-region=TEMPLATE --name=TEST"
            + TestCacheListener.class.getName())
        .statusIsError()
        .containsOutput("Template region " + SEPARATOR + "TEMPLATE does not exist");
  }

  @Test
  public void overrideListenerFromTemplate() {
    String regionName = testName.getMethodName();
    gfsh.executeAndAssertThat(
        "create region --name=" + regionName + " --type=PARTITION_REDUNDANT"
            + " --cache-listener=" + TestCacheListener.class.getName())
        .statusIsSuccess();

    gfsh.executeAndAssertThat(
        "create region --name=" + regionName + "_COPY --template-region=" + regionName
            + " --cache-listener=" + AnotherTestCacheListener.class.getName())
        .statusIsSuccess();

    server1.getVM().invoke(() -> {
      Region<?, ?> copy = ClusterStartupRule.getCache().getRegion(regionName + "_COPY");

      assertThat(Arrays.stream(copy.getAttributes().getCacheListeners())
          .map(c -> c.getClass().getName()).collect(Collectors.toSet()))
              .containsExactly(AnotherTestCacheListener.class.getName());
    });
  }


  @Test
  public void cannotSetRegionExpirationForPartitionedTemplate() {
    String regionName = testName.getMethodName();
    gfsh.executeAndAssertThat("create region --name=" + regionName + " --type=PARTITION")
        .statusIsSuccess();

    gfsh.executeAndAssertThat(
        "create region --name=" + regionName + "_COPY --template-region=" + regionName
            + " --enable-statistics=true --region-idle-time-expiration=1 --region-time-to-live-expiration=1")
        .statusIsError()
        .containsOutput(
            "ExpirationAction INVALIDATE or LOCAL_INVALIDATE for region is not supported for Partitioned Region");
  }

  @Test
  public void cannotCreateTemplateWithInconsistentPersistence() {
    String regionName = testName.getMethodName();
    gfsh.executeAndAssertThat(
        "create region --name=" + regionName + " --type=PARTITION_PERSISTENT")
        .statusIsSuccess();

    gfsh.executeAndAssertThat(
        "create region --name=" + regionName + "_COPY --template-region=" + regionName
            + " --enable-statistics=true --region-idle-time-expiration=1 --region-time-to-live-expiration=1")
        .statusIsError()
        .containsOutput(
            "ExpirationAction INVALIDATE or LOCAL_INVALIDATE for region is not supported for Partitioned Region");
  }

  @Test
  public void ensureOverridingCallbacksFromTemplateDoNotRequireClassesOnLocator() throws Exception {
    String regionName = testName.getMethodName();
    final File prJarFile = new File(tmpDir.getRoot(), "myCacheListener.jar");
    new JarBuilder().buildJar(prJarFile, getUniversalClassCode("MyCallback"),
        getUniversalClassCode("MyNewCallback"));
    gfsh.executeAndAssertThat("deploy --jar=" + prJarFile.getAbsolutePath()).statusIsSuccess();

    String myCallback = "io.pivotal.MyCallback";
    gfsh.executeAndAssertThat(
        String
            .format(
                "create region --name=" + regionName + " --type=PARTITION_REDUNDANT "
                    + "--cache-listener=%1$s " + "--cache-loader=%1$s " + "--cache-writer=%1$s "
                    + "--compressor=%1$s " + "--key-constraint=%1$s " + "--value-constraint=%1$s",
                myCallback))
        .statusIsSuccess();

    String myNewCallback = "io.pivotal.MyNewCallback";
    gfsh.executeAndAssertThat(String
        .format("create region --name=" + regionName + "_COPY --template-region=" + regionName
            + " --cache-listener=%1$s "
            + "--cache-loader=%1$s " + "--cache-writer=%1$s " + "--compressor=%1$s "
            + "--key-constraint=%1$s " + "--value-constraint=%1$s", myNewCallback))
        .statusIsSuccess();

    server1.getVM().invoke(() -> {
      Region<?, ?> copy = ClusterStartupRule.getCache().getRegion(regionName + "_COPY");

      assertThat(Arrays.stream(copy.getAttributes().getCacheListeners())
          .map(c -> c.getClass().getName()).collect(Collectors.toSet()))
              .containsExactly(myNewCallback);

      assertThat(copy.getAttributes().getCacheLoader().getClass().getName())
          .isEqualTo(myNewCallback);

      assertThat(copy.getAttributes().getCacheWriter().getClass().getName())
          .isEqualTo(myNewCallback);

      assertThat(copy.getAttributes().getCompressor().getClass().getName())
          .isEqualTo(myNewCallback);

      assertThat(copy.getAttributes().getKeyConstraint().getName()).isEqualTo(myNewCallback);

      assertThat(copy.getAttributes().getValueConstraint().getName()).isEqualTo(myNewCallback);
    });
  }

  @Test
  public void ensureNewCallbacksFromTemplateDoNotRequireClassesOnLocator() throws Exception {
    String regionName = testName.getMethodName();
    final File prJarFile = new File(tmpDir.getRoot(), "myCacheListener.jar");
    new JarBuilder().buildJar(prJarFile, getUniversalClassCode("MyNewCallback"));
    gfsh.executeAndAssertThat("deploy --jar=" + prJarFile.getAbsolutePath()).statusIsSuccess();

    gfsh.executeAndAssertThat(
        "create region --name=" + regionName + " --type=PARTITION_REDUNDANT")
        .statusIsSuccess();

    String myNewCallback = "io.pivotal.MyNewCallback";
    gfsh.executeAndAssertThat(String
        .format("create region --name=" + regionName + "_COPY --template-region=" + regionName
            + " --cache-listener=%1$s "
            + "--cache-loader=%1$s " + "--cache-writer=%1$s " + "--compressor=%1$s "
            + "--key-constraint=%1$s " + "--value-constraint=%1$s", myNewCallback))
        .statusIsSuccess();

    server1.getVM().invoke(() -> {
      Region<?, ?> copy = ClusterStartupRule.getCache().getRegion(regionName + "_COPY");

      assertThat(Arrays.stream(copy.getAttributes().getCacheListeners())
          .map(c -> c.getClass().getName()).collect(Collectors.toSet()))
              .containsExactly(myNewCallback);

      assertThat(copy.getAttributes().getCacheLoader().getClass().getName())
          .isEqualTo(myNewCallback);

      assertThat(copy.getAttributes().getCacheWriter().getClass().getName())
          .isEqualTo(myNewCallback);

      assertThat(copy.getAttributes().getCompressor().getClass().getName())
          .isEqualTo(myNewCallback);

      assertThat(copy.getAttributes().getKeyConstraint().getName()).isEqualTo(myNewCallback);

      assertThat(copy.getAttributes().getValueConstraint().getName()).isEqualTo(myNewCallback);
    });
  }

  @Test
  public void ensureOriginalCallbacksFromTemplateDoNotRequireClassesOnLocator() throws Exception {
    String regionName = testName.getMethodName();
    final File prJarFile = new File(tmpDir.getRoot(), "myCacheListener.jar");
    new JarBuilder().buildJar(prJarFile, getUniversalClassCode("MyCallback"));
    gfsh.executeAndAssertThat("deploy --jar=" + prJarFile.getAbsolutePath()).statusIsSuccess();

    String myCallback = "io.pivotal.MyCallback";
    gfsh.executeAndAssertThat(
        String
            .format(
                "create region --name=" + regionName + " --type=PARTITION_REDUNDANT "
                    + "--cache-listener=%1$s " + "--cache-loader=%1$s " + "--cache-writer=%1$s "
                    + "--compressor=%1$s " + "--key-constraint=%1$s " + "--value-constraint=%1$s",
                myCallback))
        .statusIsSuccess();

    gfsh.executeAndAssertThat(
        "create region --name=" + regionName + "_COPY --template-region=" + regionName)
        .statusIsSuccess();

    server1.getVM().invoke(() -> {
      Region<?, ?> copy = ClusterStartupRule.getCache().getRegion(regionName + "_COPY");

      assertThat(Arrays.stream(copy.getAttributes().getCacheListeners())
          .map(c -> c.getClass().getName()).collect(Collectors.toSet()))
              .containsExactly(myCallback);

      assertThat(copy.getAttributes().getCacheLoader().getClass().getName()).isEqualTo(myCallback);

      assertThat(copy.getAttributes().getCacheWriter().getClass().getName()).isEqualTo(myCallback);

      assertThat(copy.getAttributes().getCompressor().getClass().getName()).isEqualTo(myCallback);

      assertThat(copy.getAttributes().getKeyConstraint().getName()).isEqualTo(myCallback);

      assertThat(copy.getAttributes().getValueConstraint().getName()).isEqualTo(myCallback);
    });
  }

  @Test
  @SuppressWarnings("deprecation")
  public void startWithNonProxyRegion() {
    String regionName = testName.getMethodName();
    gfsh.executeAndAssertThat("create region --type=REPLICATE --group=group1 --name=" + regionName)
        .statusIsSuccess().tableHasRowWithValues("Member", "server-1");
    gfsh.executeAndAssertThat("create region --type=REPLICATE --group=group2 --name=" + regionName)
        .statusIsError()
        .containsOutput("Region " + SEPARATOR + regionName + " already exists on the cluster");

    gfsh.executeAndAssertThat("create region --type=PARTITION --group=group2 --name=" + regionName)
        .statusIsError()
        .containsOutput("Region " + SEPARATOR + regionName + " already exists on the cluster");

    gfsh.executeAndAssertThat(
        "create region --type=REPLICATE_PROXY --group=group2 --name=" + regionName)
        .statusIsSuccess().tableHasRowWithValues("Member", "server-2");

    locator.waitUntilRegionIsReadyOnExactlyThisManyServers(SEPARATOR + regionName, 2);

    gfsh.executeAndAssertThat(
        "create region --type=PARTITION_PROXY --group=group2 --name=" + regionName).statusIsError()
        .containsOutput("The existing region is not a partitioned region");
  }

  @Test
  @SuppressWarnings("deprecation")
  public void startWithReplicateProxyRegion() {
    String regionName = testName.getMethodName();
    gfsh.executeAndAssertThat(
        "create region --type=REPLICATE_PROXY --group=group1 --name=" + regionName)
        .statusIsSuccess().tableHasRowWithValues("Member", "server-1");
    gfsh.executeAndAssertThat("create region --type=REPLICATE --group=group2 --name=" + regionName)
        .statusIsSuccess().tableHasRowWithValues("Member", "server-2");

    locator.waitUntilRegionIsReadyOnExactlyThisManyServers(SEPARATOR + regionName, 2);
    // the following two should fail with name check on locator, not on server
    gfsh.executeAndAssertThat("create region --type=PARTITION --group=group2 --name=" + regionName)
        .statusIsError()
        .containsOutput("Region " + SEPARATOR + regionName + " already exists on the cluster");
    gfsh.executeAndAssertThat(
        "create region --type=PARTITION_PROXY --group=group2 --name=" + regionName).statusIsError()
        .containsOutput("The existing region is not a partitioned region");
  }

  @Test
  @SuppressWarnings("deprecation")
  public void startWithReplicateProxyThenPartitionRegion() {
    String regionName = testName.getMethodName();
    gfsh.executeAndAssertThat(
        "create region --type=REPLICATE_PROXY --group=group1 --name=" + regionName)
        .statusIsSuccess().tableHasRowWithValues("Member", "server-1");

    gfsh.executeAndAssertThat("create region --type=PARTITION --group=group2 --name=" + regionName)
        .statusIsError().containsOutput("The existing region is not a partitioned region");
    gfsh.executeAndAssertThat(
        "create region --type=PARTITION_PROXY --group=group2 --name=" + regionName).statusIsError()
        .containsOutput("The existing region is not a partitioned region");
    gfsh.executeAndAssertThat("create region --type=LOCAL --group=group2 --name=" + regionName)
        .statusIsError();
  }

  @Test
  @SuppressWarnings("deprecation")
  public void startWithPartitionProxyThenReplicate() {
    String regionName = testName.getMethodName();
    gfsh.executeAndAssertThat(
        "create region --type=PARTITION_PROXY --group=group1 --name=" + regionName)
        .statusIsSuccess().tableHasRowWithValues("Member", "server-1");
    gfsh.executeAndAssertThat("create region --type=REPLICATE --group=group2 --name=" + regionName)
        .statusIsError().containsOutput("The existing region is not a replicate region");
    gfsh.executeAndAssertThat(
        "create region --type=REPLICATE_PROXY --group=group2 --name=" + regionName).statusIsError()
        .containsOutput("The existing region is not a replicate region");
    gfsh.executeAndAssertThat("create region --type=LOCAL --group=group2 --name=" + regionName)
        .statusIsError();
  }

  @Test
  @SuppressWarnings("deprecation")
  public void startWithLocalPersistent() {
    String regionName = testName.getMethodName();
    gfsh.executeAndAssertThat(
        "create region --type=LOCAL_PERSISTENT --group=group1 --name=" + regionName)
        .statusIsSuccess().tableHasRowWithValues("Member", "server-1");
    gfsh.executeAndAssertThat("create region --type=REPLICATE --group=group2 --name=" + regionName)
        .statusIsError()
        .containsOutput(
            "Region " + SEPARATOR + "startWithLocalPersistent already exists on the cluster");
    gfsh.executeAndAssertThat("create region --type=LOCAL --group=group2 --name=" + regionName)
        .statusIsError()
        .containsOutput(
            "Region " + SEPARATOR + "startWithLocalPersistent already exists on the cluster");
  }

  @Test
  @SuppressWarnings("deprecation")
  public void startWithReplicateHeapLRU() {
    String regionName = testName.getMethodName();
    gfsh.executeAndAssertThat(
        "create region --type=REPLICATE_HEAP_LRU --group=group1 --name=" + regionName)
        .statusIsSuccess().tableHasRowWithValues("Member", "server-1");
    gfsh.executeAndAssertThat("create region --type=REPLICATE --group=group2 --name=" + regionName)
        .statusIsError().containsOutput("already exists on the cluster");
    gfsh.executeAndAssertThat("create region --type=LOCAL --group=group2 --name=" + regionName)
        .statusIsError().containsOutput("already exists on the cluster");
    gfsh.executeAndAssertThat(
        "create region --type=REPLICATE_PROXY --group=group2 --name=" + regionName)
        .statusIsSuccess();
  }

  @Test
  @SuppressWarnings("deprecation")
  public void startWithReplicateThenPartition() {
    String regionName = testName.getMethodName();
    gfsh.executeAndAssertThat("create region --type=REPLICATE --group=group1 --name=" + regionName)
        .statusIsSuccess().tableHasRowWithValues("Member", "server-1");
    gfsh.executeAndAssertThat("create region --type=PARTITION --group=group2 --name=" + regionName)
        .statusIsError().containsOutput("already exists on the cluster");
    gfsh.executeAndAssertThat(
        "create region --type=PARTITION_PROXY --group=group2 --name=" + regionName).statusIsError()
        .containsOutput("The existing region is not a partitioned region");
    gfsh.executeAndAssertThat("create region --type=LOCAL --group=group2 --name=" + regionName)
        .statusIsError().containsOutput("already exists on the cluster");
    gfsh.executeAndAssertThat(
        "create region --type=REPLICATE_PROXY --group=group1 --name=" + regionName).statusIsError()
        .containsOutput("already exists on these members: server-1");
  }

  @Test
  @SuppressWarnings("deprecation")
  public void startWithPartitionThenReplicate() {
    String regionName = testName.getMethodName();
    gfsh.executeAndAssertThat("create region --type=PARTITION --group=group1 --name=" + regionName)
        .statusIsSuccess().tableHasRowWithValues("Member", "server-1");
    gfsh.executeAndAssertThat("create region --type=REPLICATE --group=group2 --name=" + regionName)
        .statusIsError().containsOutput("already exists on the cluster");
    gfsh.executeAndAssertThat(
        "create region --type=REPLICATE_PROXY --group=group2 --name=" + regionName).statusIsError()
        .containsOutput("The existing region is not a replicate region");
    gfsh.executeAndAssertThat("create region --type=LOCAL --group=group2 --name=" + regionName)
        .statusIsError().containsOutput("already exists on the cluster");
    gfsh.executeAndAssertThat(
        "create region --type=PARTITION_PROXY --group=group1 --name=" + regionName).statusIsError()
        .containsOutput("already exists on these members: server-1");
  }

  @Test
  @SuppressWarnings("deprecation")
  public void startWithPartitionProxyRegion() {
    String regionName = testName.getMethodName();
    gfsh.executeAndAssertThat(
        "create region --type=PARTITION_PROXY --group=group1 --name=" + regionName)
        .statusIsSuccess().tableHasRowWithValues("Member", "server-1");
    gfsh.executeAndAssertThat("create region --type=PARTITION --group=group1 --name=" + regionName)
        .statusIsError().containsOutput("already exists on these members: server-1");
    gfsh.executeAndAssertThat("create region --type=PARTITION --group=group2 --name=" + regionName)
        .statusIsSuccess().tableHasRowWithValues("Member", "server-2");

    locator.waitUntilRegionIsReadyOnExactlyThisManyServers(SEPARATOR + regionName, 2);
    gfsh.executeAndAssertThat("create region --type=PARTITION --group=group2 --name=" + regionName)
        .statusIsError()
        .containsOutput("Region " + SEPARATOR + regionName + " already exists on the cluster");
    gfsh.executeAndAssertThat(
        "create region --type=REPLICATE_PROXY --group=group2 --name=" + regionName).statusIsError()
        .containsOutput("The existing region is not a replicate region");
    gfsh.executeAndAssertThat(
        "create region --type=PARTITION_PROXY --group=group1 --name=" + regionName).statusIsError()
        .containsOutput("already exists on these members: server-1");
  }

  @Test
  public void startWithLocalRegion() {
    String regionName = testName.getMethodName();
    gfsh.executeAndAssertThat("create region --type=LOCAL --group=group1 --name=" + regionName)
        .statusIsSuccess();
    gfsh.executeAndAssertThat("create region --type=REPLICATE --name=" + regionName).statusIsError()
        .containsOutput(
            "Region " + SEPARATOR + "startWithLocalRegion already exists on the cluster.");
    gfsh.executeAndAssertThat("create region --type=PARTITION --group=group2 --name=" + regionName)
        .statusIsError()
        .containsOutput(
            "Region " + SEPARATOR + "startWithLocalRegion already exists on the cluster.");
    gfsh.executeAndAssertThat(
        "create region --type=PARTITION_PROXY --group=group2 --name=" + regionName).statusIsError()
        .containsOutput(
            "Region " + SEPARATOR + "startWithLocalRegion already exists on the cluster");
  }

  @Test
  public void cannotDisableCloningWhenCompressorIsSet() {
    String regionName = testName.getMethodName();
    gfsh.executeAndAssertThat("create region"
        + " --name=" + regionName
        + " --type=REPLICATE"
        + " --compressor=" + DummyCompressor.class.getName()
        + " --enable-cloning=false").statusIsError();
  }

  @Test
  public void cannotColocateWithNonexistentRegion() {
    String regionName = testName.getMethodName();
    gfsh.executeAndAssertThat("create region"
        + " --name=" + regionName
        + " --type=PARTITION"
        + " --colocated-with=" + SEPARATOR + "nonexistent").statusIsError()
        .containsOutput("Specify a valid region path for colocated-with")
        .containsOutput("nonexistent not found");
  }

  @Test
  public void cannotColocateWithNonPartitionedRegion() {
    gfsh.executeAndAssertThat(
        "create region --type=REPLICATE --name=" + SEPARATOR + "nonpartitioned")
        .statusIsSuccess();

    String regionName = testName.getMethodName();
    gfsh.executeAndAssertThat("create region"
        + " --name=" + regionName
        + " --type=PARTITION"
        + " --colocated-with=" + SEPARATOR + "nonpartitioned").statusIsError()
        .containsOutput("\"" + SEPARATOR + "nonpartitioned\" is not a Partitioned Region");
  }

  @Test
  public void cannotCreateSubregionOnNonExistentParentRegion() {
    gfsh.executeAndAssertThat("create region --type=REPLICATE --name=" + SEPARATOR
        + "nonexistentparent" + SEPARATOR + "child")
        .statusIsError()
        .containsOutput("Parent region for \"" + SEPARATOR + "nonexistentparent" + SEPARATOR
            + "child\" does not exist");
  }

  @Test
  public void cannotCreateWithNonexistentGatewaySenders() {
    gfsh.executeAndAssertThat(
        "create region --type=REPLICATE --name=" + SEPARATOR
            + "invalid --gateway-sender-id=nonexistent")
        .statusIsError()
        .containsOutput("There are no GatewaySenders");
  }

  @Test
  public void testCreateRegionFromTemplateWithAsyncEventListeners() {
    String queueId = "queue1";
    gfsh.executeAndAssertThat(
        "create async-event-queue --id=" + queueId
            + " --listener=" + CreateRegionCommandDUnitTest.DummyAEQListener.class.getName())
        .statusIsSuccess();

    String regionName = testName.getMethodName();
    gfsh.executeAndAssertThat(
        "create region --name=" + regionName
            + " --type=REPLICATE"
            + " --async-event-queue-id=" + queueId)
        .statusIsSuccess();

    gfsh.executeAndAssertThat(
        "create region --name=" + regionName + "-from-template"
            + " --template-region=" + regionName)
        .statusIsSuccess();

    server1.invoke(() -> {
      Region<?, ?> regionFromTemplate = ClusterStartupRule.getCache()
          .getRegion(regionName + "-from-template");
      assertThat(regionFromTemplate).isNotNull();
      @SuppressWarnings("unchecked")
      final Set<String> asyncEventQueueIds =
          ((InternalRegion) regionFromTemplate).getAsyncEventQueueIds();
      assertThat(asyncEventQueueIds).contains(queueId);
    });
  }

  @Test
  public void testCreateRegionFromTemplateWithPartitionResolver() {
    String regionName = testName.getMethodName();
    String regionFromTemplateName = regionName + "-from-template";

    gfsh.executeAndAssertThat("create region"
        + " --name=" + regionName
        + " --type=PARTITION"
        + " --partition-resolver=" + DummyPartitionResolver.class.getName()).statusIsSuccess();
    gfsh.executeAndAssertThat("create region"
        + " --name=" + regionFromTemplateName
        + " --template-region=" + regionName).statusIsSuccess();

    server1.invoke(() -> {
      Region<?, ?> regionFromTemplate = ClusterStartupRule.getCache()
          .getRegion(regionName + "-from-template");
      assertThat(regionFromTemplate).isNotNull();
      assertThat(((InternalRegion) regionFromTemplate).getPartitionAttributes()
          .getPartitionResolver())
              .isNotNull();
      assertThat(((InternalRegion) regionFromTemplate).getPartitionAttributes()
          .getPartitionResolver().getName())
              .isEqualTo("dummy");
    });
  }

  @Test
  @SuppressWarnings("deprecation")
  public void createRegionCommandCreateCorrectClusterConfigXml() {
    URL xmlResource =
        CreateRegionCommandDUnitTest.class.getResource("CreateRegionCommandDUnitTest.xml");

    RegionShortcut[] shortcuts = RegionShortcut.values();
    for (RegionShortcut shortcut : shortcuts) {
      gfsh.executeAndAssertThat(
          "create region --name=" + shortcut.name() + " --type=" + shortcut.name());
    }

    locator.invoke(() -> {
      InternalConfigurationPersistenceService persistenceService =
          ClusterStartupRule.getLocator().getConfigurationPersistenceService();
      CacheConfig expected = persistenceService.getJaxbService()
          .unMarshall(FileUtils.readFileToString(new File(xmlResource.getFile()), "UTF-8"));

      CacheConfig actual = persistenceService.getCacheConfig("cluster");

      for (RegionShortcut shortcut : shortcuts) {
        assertThat(find(actual.getRegions(), shortcut.name()))
            .isEqualToComparingFieldByFieldRecursively(
                find(expected.getRegions(), shortcut.name()));
      }
    });
  }

  private String getUniversalClassCode(String classname) {
    return "package io.pivotal;" + "import org.apache.geode.cache.CacheLoader;"
        + "import org.apache.geode.cache.CacheLoaderException;"
        + "import org.apache.geode.cache.CacheWriter;"
        + "import org.apache.geode.cache.CacheWriterException;"
        + "import org.apache.geode.cache.EntryEvent;"
        + "import org.apache.geode.cache.LoaderHelper;"
        + "import org.apache.geode.cache.RegionEvent;"
        + "import org.apache.geode.cache.util.CacheListenerAdapter;"
        + "import org.apache.geode.compression.Compressor;" + "public class " + classname
        + " extends CacheListenerAdapter "
        + "implements CacheWriter, CacheLoader, Compressor, java.io.Serializable {"
        + "public void beforeUpdate(EntryEvent event) throws CacheWriterException {}"
        + "public void beforeCreate(EntryEvent event) throws CacheWriterException {}"
        + "public void beforeDestroy(EntryEvent event) throws CacheWriterException {}"
        + "public void beforeRegionDestroy(RegionEvent event) throws CacheWriterException {}"
        + "public void beforeRegionClear(RegionEvent event) throws CacheWriterException {}"
        + "public Object load(LoaderHelper helper) throws CacheLoaderException { return null; }"
        + "public byte[] compress(byte[] input) { return new byte[0]; }"
        + "public byte[] decompress(byte[] input) { return new byte[0]; }" + "}";
  }

}
