/*
 * 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.internal.cache;

import static org.apache.geode.distributed.ConfigurationProperties.OFF_HEAP_MEMORY_SIZE;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.fail;

import java.util.Properties;

import org.junit.Test;
import org.junit.experimental.categories.Category;

import org.apache.geode.cache.CacheException;
import org.apache.geode.cache.PartitionAttributes;
import org.apache.geode.cache.PartitionAttributesFactory;
import org.apache.geode.cache.Region;
import org.apache.geode.cache.RegionFactory;
import org.apache.geode.cache.RegionShortcut;
import org.apache.geode.cache30.CacheSerializableRunnable;
import org.apache.geode.test.dunit.Host;
import org.apache.geode.test.dunit.IgnoredException;
import org.apache.geode.test.dunit.Invoke;
import org.apache.geode.test.dunit.SerializableRunnable;
import org.apache.geode.test.dunit.cache.internal.JUnit4CacheTestCase;
import org.apache.geode.test.junit.categories.OffHeapTest;

@Category({OffHeapTest.class})
public class DistrbutedRegionProfileOffHeapDUnitTest extends JUnit4CacheTestCase {

  @Override
  public final void preTearDownAssertions() throws Exception {
    SerializableRunnable checkOrphans = new SerializableRunnable() {

      @Override
      public void run() {
        if (hasCache()) {
          OffHeapTestUtil.checkOrphans(getCache());
        }
      }
    };
    Invoke.invokeInEveryVM(checkOrphans);
    checkOrphans.run();
  }

  /**
   * Asserts that creating a region on two members, with one member having the region as on-heap and
   * the other as having the region as off-heap, will cause an exception and the region will not be
   * created.
   */
  @Test
  public void testPartitionedRegionProfileWithConflict() throws Exception {
    final String regionName = getTestMethodName() + "Region";

    Host.getHost(0).getVM(0).invoke(new CacheSerializableRunnable("createRegionNoException") {
      private static final long serialVersionUID = 1L;

      @Override
      public void run2() throws CacheException {
        disconnectFromDS();
        Properties properties = new Properties();
        properties.put(OFF_HEAP_MEMORY_SIZE, "2m");
        getSystem(properties);

        GemFireCacheImpl cache = (GemFireCacheImpl) getCache();
        RegionFactory regionFactory = cache.createRegionFactory(RegionShortcut.PARTITION);
        regionFactory.setOffHeap(true);
        Region region = regionFactory.create(regionName);

        assertNotNull("Region is null", region);
        assertNotNull("Cache does not contain region", cache.getRegion(regionName));
      }
    });

    Host.getHost(0).getVM(1).invoke(new CacheSerializableRunnable("createRegionException") {
      private static final long serialVersionUID = 1L;

      @SuppressWarnings("synthetic-access")
      @Override
      public void run2() throws CacheException {
        disconnectFromDS();
        final GemFireCacheImpl cache = (GemFireCacheImpl) getCache();
        final RegionFactory regionFactory = cache.createRegionFactory(RegionShortcut.PARTITION);
        Region region = null;

        try {
          IgnoredException.addIgnoredException("IllegalStateException");
          region = regionFactory.create(regionName);
          fail("Expected exception upon creation with invalid off-heap state");
        } catch (IllegalStateException expected) {
          // An exception is expected.
        } finally {
          removeExceptionTag1("IllegalStateException");
        }

        assertNull("Region is not null", region);
        assertNull("Cache contains region", cache.getRegion(regionName));
      }
    });
  }

  /**
   * Asserts that creating a region on two members, with both regions having the same off-heap
   * status, will not cause an exception and the region will be created.
   */
  @Test
  public void testPartitionedRegionProfileWithoutConflict() throws Exception {
    final String offHeapRegionName = getTestMethodName() + "OffHeapRegion";
    final String onHeapRegionName = getTestMethodName() + "OnHeapRegion";

    for (int vmId = 0; vmId <= 1; vmId++) {
      Host.getHost(0).getVM(vmId).invoke(new CacheSerializableRunnable("createRegionNoException") {
        private static final long serialVersionUID = 1L;

        @Override
        public void run2() throws CacheException {
          disconnectFromDS();
          Properties properties = new Properties();
          properties.put(OFF_HEAP_MEMORY_SIZE, "2m");
          getSystem(properties);

          GemFireCacheImpl cache = (GemFireCacheImpl) getCache();
          RegionFactory regionFactory = cache.createRegionFactory(RegionShortcut.PARTITION);
          regionFactory.setOffHeap(true);
          Region region = regionFactory.create(offHeapRegionName);

          assertNotNull("Region is null", region);
          assertNotNull("Cache does not contain region", cache.getRegion(offHeapRegionName));

          regionFactory = cache.createRegionFactory(RegionShortcut.PARTITION);
          regionFactory.create(onHeapRegionName);

          assertNotNull("Region is null", region);
          assertNotNull("Cache does not contain region", cache.getRegion(onHeapRegionName));
        }
      });
    }
  }

  /**
   * Asserts that creating a region on two members, with one being off-heap with local storage and
   * the other being on-heap without local storage, will not cause an exception.
   */
  @Test
  public void testPartitionedRegionProfileWithAccessor() throws Exception {
    final String regionName = getTestMethodName() + "Region";

    // Create a region using off-heap
    Host.getHost(0).getVM(0).invoke(new CacheSerializableRunnable("createRegionNoException") {
      private static final long serialVersionUID = 1L;

      @Override
      public void run2() throws CacheException {
        disconnectFromDS();
        Properties properties = new Properties();
        properties.put(OFF_HEAP_MEMORY_SIZE, "2m");
        getSystem(properties);

        GemFireCacheImpl cache = (GemFireCacheImpl) getCache();
        RegionFactory regionFactory = cache.createRegionFactory(RegionShortcut.PARTITION);
        regionFactory.setOffHeap(true);
        Region region = regionFactory.create(regionName);

        assertNotNull("Region is null", region);
        assertNotNull("Cache does not contain region", cache.getRegion(regionName));
      }
    });

    // Create an accessor (no local storage) for the same region
    Host.getHost(0).getVM(1).invoke(new CacheSerializableRunnable("createRegionNoException") {
      private static final long serialVersionUID = 1L;

      @Override
      public void run2() throws CacheException {
        disconnectFromDS();
        Properties properties = new Properties();
        properties.put(OFF_HEAP_MEMORY_SIZE, "2m");
        getSystem(properties);

        GemFireCacheImpl cache = (GemFireCacheImpl) getCache();
        RegionFactory regionFactory = cache.createRegionFactory(RegionShortcut.PARTITION);

        PartitionAttributes partitionAttributes =
            new PartitionAttributesFactory().setLocalMaxMemory(0).create();
        regionFactory.setPartitionAttributes(partitionAttributes);

        Region region = regionFactory.create(regionName);

        assertNotNull("Region is null", region);
        assertNotNull("Cache does not contain region", cache.getRegion(regionName));
      }
    });
  }

  /**
   * Asserts that creating a region on two members, with one being off-heap with local storage and
   * the other being a proxy will not cause an exception.
   */
  @Test
  public void testPartitionedRegionProfileWithProxy() throws Exception {
    final String regionName = getTestMethodName() + "Region";

    // Create a region using off-heap
    Host.getHost(0).getVM(0).invoke(new CacheSerializableRunnable("createRegionNoException") {
      private static final long serialVersionUID = 1L;

      @Override
      public void run2() throws CacheException {
        disconnectFromDS();
        Properties properties = new Properties();
        properties.put(OFF_HEAP_MEMORY_SIZE, "2m");
        getSystem(properties);

        GemFireCacheImpl cache = (GemFireCacheImpl) getCache();
        RegionFactory regionFactory = cache.createRegionFactory(RegionShortcut.PARTITION);
        regionFactory.setOffHeap(true);
        Region region = regionFactory.create(regionName);

        assertNotNull("Region is null", region);
        assertNotNull("Cache does not contain region", cache.getRegion(regionName));
      }
    });

    // Create a proxy for the same region
    Host.getHost(0).getVM(1).invoke(new CacheSerializableRunnable("createRegionNoException") {
      private static final long serialVersionUID = 1L;

      @Override
      public void run2() throws CacheException {
        disconnectFromDS();
        Properties properties = new Properties();
        properties.put(OFF_HEAP_MEMORY_SIZE, "2m");
        getSystem(properties);

        GemFireCacheImpl cache = (GemFireCacheImpl) getCache();
        RegionFactory regionFactory = cache.createRegionFactory(RegionShortcut.PARTITION_PROXY);
        Region region = regionFactory.create(regionName);

        assertNotNull("Region is null", region);
        assertNotNull("Cache does not contain region", cache.getRegion(regionName));
      }
    });
  }
}
