/*
 * 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 static org.junit.Assert.assertEquals;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.stream.Collectors;

import org.junit.After;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.ClassRule;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.junit.rules.TemporaryFolder;

import org.apache.geode.cache.EvictionAlgorithm;
import org.apache.geode.cache.EvictionAttributes;
import org.apache.geode.cache.ExpirationAction;
import org.apache.geode.cache.ExpirationAttributes;
import org.apache.geode.cache.Region;
import org.apache.geode.cache.RegionAttributes;
import org.apache.geode.cache.configuration.CacheConfig;
import org.apache.geode.cache.configuration.EnumActionDestroyOverflow;
import org.apache.geode.cache.configuration.RegionAttributesType;
import org.apache.geode.cache.configuration.RegionConfig;
import org.apache.geode.test.compiler.ClassBuilder;
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.RegionsTest;
import org.apache.geode.test.junit.rules.GfshCommandRule;
import org.apache.geode.test.junit.rules.VMProvider;

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

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

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

  @ClassRule
  public static TemporaryFolder temporaryFolder = new TemporaryFolder();

  private static MemberVM locator, server1, server2, server3;

  @BeforeClass
  public static void beforeClass() throws Exception {
    locator = cluster.startLocatorVM(0);
    server1 = cluster.startServerVM(1, "group1", locator.getPort());
    server2 = cluster.startServerVM(2, locator.getPort());
    server3 = cluster.startServerVM(3, locator.getPort());

    gfsh.connectAndVerify(locator);

    deployJarFilesForRegionAlter();
  }

  @Before
  public void before() throws Exception {
    // make sure all tests started with no region defined
    gfsh.executeAndAssertThat("list regions").statusIsSuccess().containsOutput("No Regions Found");
  }

  @After
  public void after() throws Exception {
    // make sure all tests started with no region defined
    gfsh.executeAndAssertThat("destroy region --name=regionA --if-exists").statusIsSuccess();
  }

  @Test
  public void alterRegionResetCacheListeners() throws Exception {
    gfsh.executeAndAssertThat("create region --name=regionA --type=PARTITION").statusIsSuccess();

    String listenerABC =
        "com.cadrdunit.RegionAlterCacheListenerA,com.cadrdunit.RegionAlterCacheListenerB,com.cadrdunit.RegionAlterCacheListenerC";
    gfsh.executeAndAssertThat("alter region --name=regionA --cache-listener=" + listenerABC)
        .statusIsSuccess().tableHasRowCount(3);

    VMProvider.invokeInEveryMember(() -> {
      RegionAttributes attributes =
          ClusterStartupRule.getCache().getRegion("regionA").getAttributes();
      assertEquals(3, attributes.getCacheListeners().length);

      assertThat(Arrays.stream(attributes.getCacheListeners()).map(c -> c.getClass().getName())
          .collect(Collectors.toSet())).containsExactlyInAnyOrder(
              "com.cadrdunit.RegionAlterCacheListenerA", "com.cadrdunit.RegionAlterCacheListenerB",
              "com.cadrdunit.RegionAlterCacheListenerC");
    }, server1, server2, server3);

    // alter region on a group instead of "cluster"
    gfsh.executeAndAssertThat("alter region --group=group1 --name=regionA --cache-listener=''")
        .statusIsError()
        .hasInfoSection()
        .hasOutput().contains(SEPARATOR + "regionA does not exist in group group1");

    // since this region exists on "cluster" group, we can only alter it with a "cluster" group
    gfsh.executeAndAssertThat("alter region --name=regionA --cache-listener=''")
        .statusIsSuccess()
        .hasTableSection().hasRowSize(3)
        .hasRow(0)
        .containsExactly("server-1", "OK", "Region regionA altered");
    // remove listener on server1
    server1.invoke(() -> {
      RegionAttributes attributes =
          ClusterStartupRule.getCache().getRegion("regionA").getAttributes();
      assertEquals(0, attributes.getCacheListeners().length);
    });
  }

  @Test
  public void alterEntryIdleTimeExpiration() {
    gfsh.executeAndAssertThat(
        "create region --name=regionA --type=REPLICATE --entry-idle-time-expiration=10 --enable-statistics")
        .statusIsSuccess();

    server1.invoke(() -> {
      Region region = ClusterStartupRule.getCache().getRegion("regionA");
      ExpirationAttributes expiry = region.getAttributes().getEntryIdleTimeout();
      assertThat(expiry.getTimeout()).isEqualTo(10);
      assertThat(expiry.getAction()).isEqualTo(ExpirationAction.INVALIDATE);
    });

    gfsh.executeAndAssertThat(
        "alter region --name=regionA --entry-idle-time-expiration-action=DESTROY")
        .statusIsSuccess();
    server1.invoke(() -> {
      Region region = ClusterStartupRule.getCache().getRegion("regionA");
      ExpirationAttributes expiry = region.getAttributes().getEntryIdleTimeout();
      assertThat(expiry.getTimeout()).isEqualTo(10);
      assertThat(expiry.getAction()).isEqualTo(ExpirationAction.DESTROY);
    });

    gfsh.executeAndAssertThat("alter region --name=regionA --entry-idle-time-expiration=5")
        .statusIsSuccess();
    server1.invoke(() -> {
      Region region = ClusterStartupRule.getCache().getRegion("regionA");
      ExpirationAttributes expiry = region.getAttributes().getEntryIdleTimeout();
      assertThat(expiry.getTimeout()).isEqualTo(5);
      assertThat(expiry.getAction()).isEqualTo(ExpirationAction.DESTROY);
    });
  }


  @Test
  public void alterEntryIdleTimeExpirationAction() {
    gfsh.executeAndAssertThat(
        "create region --name=regionA --type=REPLICATE --entry-idle-time-expiration-action=destroy --enable-statistics")
        .statusIsSuccess();

    server1.invoke(() -> {
      Region region = ClusterStartupRule.getCache().getRegion("regionA");
      ExpirationAttributes expiry = region.getAttributes().getEntryIdleTimeout();
      assertThat(expiry.getTimeout()).isEqualTo(0);
      assertThat(expiry.getAction()).isEqualTo(ExpirationAction.DESTROY);
    });

    gfsh.executeAndAssertThat(
        "alter region --name=regionA --entry-idle-time-expiration-action=invalidate")
        .statusIsSuccess();
    server1.invoke(() -> {
      Region region = ClusterStartupRule.getCache().getRegion("regionA");
      ExpirationAttributes expiry = region.getAttributes().getEntryIdleTimeout();
      assertThat(expiry.getTimeout()).isEqualTo(0);
      assertThat(expiry.getAction()).isEqualTo(ExpirationAction.INVALIDATE);
    });

    gfsh.executeAndAssertThat("alter region --name=regionA --entry-idle-time-expiration=5")
        .statusIsSuccess();
    server1.invoke(() -> {
      Region region = ClusterStartupRule.getCache().getRegion("regionA");
      ExpirationAttributes expiry = region.getAttributes().getEntryIdleTimeout();
      assertThat(expiry.getTimeout()).isEqualTo(5);
      assertThat(expiry.getAction()).isEqualTo(ExpirationAction.INVALIDATE);
    });
  }

  @Test
  public void alterRegionStatisticsNotEnabled() {
    IgnoredException.addIgnoredException(
        "java.lang.IllegalStateException: Cannot set idle timeout when statistics are disabled");
    gfsh.executeAndAssertThat("create region --name=regionA --type=REPLICATE").statusIsSuccess();
    gfsh.executeAndAssertThat(
        "alter region --name=regionA --entry-idle-time-expiration-action=invalidate")
        .statusIsError()
        .containsOutput("Cannot set idle timeout when statistics are disabled.");

    gfsh.executeAndAssertThat(
        "alter region --name=regionA --entry-idle-time-custom-expiry=com.cadrdunit.RegionAlterCustomExpiry")
        .statusIsError()
        .containsOutput("Cannot set idle timeout when statistics are disabled.");
  }

  @Test
  public void alterExpirationAttributesWithStatisticsEnabled() {
    gfsh.executeAndAssertThat("create region --name=regionA --type=REPLICATE --enable-statistics")
        .statusIsSuccess();
    gfsh.executeAndAssertThat(
        "alter region --name=regionA --entry-idle-time-expiration-action=invalidate")
        .statusIsSuccess();

    gfsh.executeAndAssertThat(
        "alter region --name=regionA --entry-idle-time-custom-expiry=com.cadrdunit.RegionAlterCustomExpiry")
        .statusIsSuccess();

    server1.invoke(() -> {
      Region region = ClusterStartupRule.getCache().getRegion("regionA");
      ExpirationAttributes expiry = region.getAttributes().getEntryIdleTimeout();
      assertThat(expiry.getTimeout()).isEqualTo(0);
      assertThat(expiry.getAction()).isEqualTo(ExpirationAction.INVALIDATE);
      assertThat(region.getAttributes().getCustomEntryIdleTimeout().getClass().getName())
          .isEqualTo("com.cadrdunit.RegionAlterCustomExpiry");
    });

    gfsh.executeAndAssertThat("alter region --name=regionA --entry-idle-time-custom-expiry=''")
        .statusIsSuccess();

    server1.invoke(() -> {
      Region region = ClusterStartupRule.getCache().getRegion("regionA");
      ExpirationAttributes expiry = region.getAttributes().getEntryIdleTimeout();
      assertThat(expiry.getTimeout()).isEqualTo(0);
      assertThat(expiry.getAction()).isEqualTo(ExpirationAction.INVALIDATE);
      assertThat(region.getAttributes().getCustomEntryIdleTimeout()).isNull();
    });
  }

  @Test
  public void alterEvictionMaxOnRegionWithoutEvictionAttributesHasNoEffect() throws Exception {
    gfsh.executeAndAssertThat("create region --name=regionA --type=REPLICATE").statusIsSuccess();
    locator.waitUntilRegionIsReadyOnExactlyThisManyServers(SEPARATOR + "regionA", 3);

    gfsh.executeAndAssertThat("alter region --name=regionA --eviction-max=20").statusIsSuccess();

    locator.invoke(() -> {
      CacheConfig config = ClusterStartupRule.getLocator().getConfigurationPersistenceService()
          .getCacheConfig("cluster");
      RegionConfig regionConfig = find(config.getRegions(), "regionA");
      RegionAttributesType.EvictionAttributes evictionAttributes =
          regionConfig.getRegionAttributes().getEvictionAttributes();
      assertThat(evictionAttributes).isNull();
    });

    server1.invoke(() -> {
      Region region = ClusterStartupRule.getCache().getRegion(SEPARATOR + "regionA");
      EvictionAttributes evictionAttributes = region.getAttributes().getEvictionAttributes();
      assertThat(evictionAttributes.getAlgorithm()).isEqualTo(EvictionAlgorithm.NONE);
    });
  }

  @Test
  public void alterRegionWithEvictionMaxOnRegionWithEviction() throws Exception {
    gfsh.executeAndAssertThat(
        "create region --name=regionA --type=REPLICATE --eviction-entry-count=20 --eviction-action=local-destroy")
        .statusIsSuccess();
    locator.waitUntilRegionIsReadyOnExactlyThisManyServers(SEPARATOR + "regionA", 3);

    gfsh.executeAndAssertThat("alter region --name=regionA --eviction-max=30").statusIsSuccess();

    locator.invoke(() -> {
      CacheConfig config = ClusterStartupRule.getLocator().getConfigurationPersistenceService()
          .getCacheConfig("cluster");
      RegionConfig regionConfig = find(config.getRegions(), "regionA");
      RegionAttributesType.EvictionAttributes evictionAttributes =
          regionConfig.getRegionAttributes().getEvictionAttributes();
      assertThat(evictionAttributes.getLruEntryCount().getMaximum()).isEqualTo("30");
      assertThat(evictionAttributes.getLruEntryCount().getAction()).isEqualTo(
          EnumActionDestroyOverflow.LOCAL_DESTROY);
    });
  }

  private static void deployJarFilesForRegionAlter() throws IOException {
    ClassBuilder classBuilder = new ClassBuilder();
    final File jarFile1 = new File(temporaryFolder.getRoot(), "testAlterRegion1.jar");
    final File jarFile2 = new File(temporaryFolder.getRoot(), "testAlterRegion2.jar");
    final File jarFile3 = new File(temporaryFolder.getRoot(), "testAlterRegion3.jar");
    final File jarFile4 = new File(temporaryFolder.getRoot(), "testAlterRegion4.jar");
    final File jarFile5 = new File(temporaryFolder.getRoot(), "testAlterRegion5.jar");
    final File jarFile6 = new File(temporaryFolder.getRoot(), "testAlterRegion6.jar");


    byte[] jarBytes =
        classBuilder.createJarFromClassContent("com/cadrdunit/RegionAlterCacheListenerA",
            "package com.cadrdunit;" + "import org.apache.geode.cache.util.CacheListenerAdapter;"
                + "public class RegionAlterCacheListenerA extends CacheListenerAdapter {}");
    writeJarBytesToFile(jarFile1, jarBytes);
    gfsh.executeAndAssertThat("deploy --jar=" + jarFile1.getAbsolutePath()).statusIsSuccess();

    jarBytes = classBuilder.createJarFromClassContent("com/cadrdunit/RegionAlterCacheListenerB",
        "package com.cadrdunit;" + "import org.apache.geode.cache.util.CacheListenerAdapter;"
            + "public class RegionAlterCacheListenerB extends CacheListenerAdapter {}");
    writeJarBytesToFile(jarFile2, jarBytes);
    gfsh.executeAndAssertThat("deploy --jar=" + jarFile2.getAbsolutePath()).statusIsSuccess();

    jarBytes = classBuilder.createJarFromClassContent("com/cadrdunit/RegionAlterCacheListenerC",
        "package com.cadrdunit;" + "import org.apache.geode.cache.util.CacheListenerAdapter;"
            + "public class RegionAlterCacheListenerC extends CacheListenerAdapter {}");
    writeJarBytesToFile(jarFile3, jarBytes);
    gfsh.executeAndAssertThat("deploy --jar=" + jarFile3.getAbsolutePath()).statusIsSuccess();

    jarBytes = classBuilder.createJarFromClassContent("com/cadrdunit/RegionAlterCacheLoader",
        "package com.cadrdunit;" + "import org.apache.geode.cache.CacheLoader;"
            + "import org.apache.geode.cache.CacheLoaderException;"
            + "import org.apache.geode.cache.LoaderHelper;"
            + "public class RegionAlterCacheLoader implements CacheLoader {"
            + "public void close() {}"
            + "public Object load(LoaderHelper helper) throws CacheLoaderException {return null;}}");
    writeJarBytesToFile(jarFile4, jarBytes);
    gfsh.executeAndAssertThat("deploy --jar=" + jarFile4.getAbsolutePath()).statusIsSuccess();

    jarBytes = classBuilder.createJarFromClassContent("com/cadrdunit/RegionAlterCacheWriter",
        "package com.cadrdunit;" + "import org.apache.geode.cache.util.CacheWriterAdapter;"
            + "public class RegionAlterCacheWriter extends CacheWriterAdapter {}");
    writeJarBytesToFile(jarFile5, jarBytes);
    gfsh.executeAndAssertThat("deploy --jar=" + jarFile5.getAbsolutePath()).statusIsSuccess();

    jarBytes = classBuilder.createJarFromClassContent("com/cadrdunit/RegionAlterCustomExpiry",
        "package com.cadrdunit;" + "import org.apache.geode.cache.CustomExpiry;"
            + "import org.apache.geode.cache.Region.Entry;"
            + "import org.apache.geode.cache.ExpirationAttributes;"
            + "public class RegionAlterCustomExpiry implements CustomExpiry {"
            + "public void close() {}"
            + "public ExpirationAttributes getExpiry(Entry entry) {return null;}" + "}");
    writeJarBytesToFile(jarFile6, jarBytes);
    gfsh.executeAndAssertThat("deploy --jar=" + jarFile6.getAbsolutePath()).statusIsSuccess();
  }

  private static void writeJarBytesToFile(File jarFile, byte[] jarBytes) throws IOException {
    final OutputStream outStream = new FileOutputStream(jarFile);
    outStream.write(jarBytes);
    outStream.flush();
    outStream.close();
  }
}
