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

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;

import org.junit.Rule;
import org.junit.Test;
import org.junit.contrib.java.lang.system.RestoreSystemProperties;

import org.apache.geode.OutOfOffHeapMemoryException;
import org.apache.geode.StatisticsFactory;
import org.apache.geode.distributed.internal.DistributionStats;
import org.apache.geode.distributed.internal.InternalDistributedSystem;
import org.apache.geode.distributed.internal.InternalLocator;
import org.apache.geode.internal.offheap.MemoryAllocatorImpl.DummyNonRealTimeStatsUpdater;
import org.apache.geode.internal.statistics.LocalStatisticsFactory;
import org.apache.geode.util.internal.GeodeGlossary;

public class OffHeapStorageJUnitTest {

  private static final long MEGABYTE = 1024 * 1024;
  private static final long GIGABYTE = 1024 * 1024 * 1024;

  @Rule
  public final RestoreSystemProperties restoreSystemProperties = new RestoreSystemProperties();

  @Test
  public void testParseOffHeapMemorySizeNegative() {
    assertEquals(0, OffHeapStorage.parseOffHeapMemorySize("-1"));
  }

  @Test
  public void testParseOffHeapMemorySizeNull() {
    assertEquals(0, OffHeapStorage.parseOffHeapMemorySize(null));
  }

  @Test
  public void testParseOffHeapMemorySizeEmpty() {
    assertEquals(0, OffHeapStorage.parseOffHeapMemorySize(""));
  }

  @Test
  public void testParseOffHeapMemorySizeBytes() {
    assertEquals(MEGABYTE, OffHeapStorage.parseOffHeapMemorySize("1"));
    assertEquals(Integer.MAX_VALUE * MEGABYTE,
        OffHeapStorage.parseOffHeapMemorySize("" + Integer.MAX_VALUE));
  }

  @Test
  public void testParseOffHeapMemorySizeKiloBytes() {
    try {
      OffHeapStorage.parseOffHeapMemorySize("1k");
      fail("Did not receive expected IllegalArgumentException");
    } catch (IllegalArgumentException expected) {
      // Expected
    }
  }

  @Test
  public void testParseOffHeapMemorySizeMegaBytes() {
    assertEquals(MEGABYTE, OffHeapStorage.parseOffHeapMemorySize("1m"));
    assertEquals(Integer.MAX_VALUE * MEGABYTE,
        OffHeapStorage.parseOffHeapMemorySize("" + Integer.MAX_VALUE + "m"));
  }

  @Test
  public void testParseOffHeapMemorySizeGigaBytes() {
    assertEquals(GIGABYTE, OffHeapStorage.parseOffHeapMemorySize("1g"));
    assertEquals(Integer.MAX_VALUE * GIGABYTE,
        OffHeapStorage.parseOffHeapMemorySize("" + Integer.MAX_VALUE + "g"));
  }

  @Test
  public void testCalcMaxSlabSize() {
    assertEquals(100, OffHeapStorage.calcMaxSlabSize(100L));
    assertEquals(Integer.MAX_VALUE, OffHeapStorage.calcMaxSlabSize(Long.MAX_VALUE));
    try {
      System.setProperty(GeodeGlossary.GEMFIRE_PREFIX + "OFF_HEAP_SLAB_SIZE", "99");
      assertEquals(99 * 1024 * 1024, OffHeapStorage.calcMaxSlabSize(100L * 1024 * 1024));
      assertEquals(88, OffHeapStorage.calcMaxSlabSize(88));
      System.setProperty(GeodeGlossary.GEMFIRE_PREFIX + "OFF_HEAP_SLAB_SIZE", "88m");
      assertEquals(88 * 1024 * 1024, OffHeapStorage.calcMaxSlabSize(100L * 1024 * 1024));
      System.setProperty(GeodeGlossary.GEMFIRE_PREFIX + "OFF_HEAP_SLAB_SIZE", "77M");
      assertEquals(77 * 1024 * 1024, OffHeapStorage.calcMaxSlabSize(100L * 1024 * 1024));
      System.setProperty(GeodeGlossary.GEMFIRE_PREFIX + "OFF_HEAP_SLAB_SIZE", "1g");
      assertEquals(1 * 1024 * 1024 * 1024, OffHeapStorage.calcMaxSlabSize(2L * 1024 * 1024 * 1024));
      System.setProperty(GeodeGlossary.GEMFIRE_PREFIX + "OFF_HEAP_SLAB_SIZE", "1G");
      assertEquals(1L * 1024 * 1024 * 1024,
          OffHeapStorage.calcMaxSlabSize(2L * 1024 * 1024 * 1024 + 1));
      System.setProperty(GeodeGlossary.GEMFIRE_PREFIX + "OFF_HEAP_SLAB_SIZE", "foobarG");
      try {
        OffHeapStorage.calcMaxSlabSize(100);
        fail("expected IllegalArgumentException");
      } catch (IllegalArgumentException expected) {
      }
      System.setProperty(GeodeGlossary.GEMFIRE_PREFIX + "OFF_HEAP_SLAB_SIZE", "");
      assertEquals(100, OffHeapStorage.calcMaxSlabSize(100L));
      assertEquals(Integer.MAX_VALUE, OffHeapStorage.calcMaxSlabSize(Long.MAX_VALUE));
    } finally {
      System.clearProperty(GeodeGlossary.GEMFIRE_PREFIX + "OFF_HEAP_SLAB_SIZE");
    }
  }

  @Test
  public void createOffHeapStorageReturnsNullIfForceLocator() {
    System.setProperty(InternalLocator.FORCE_LOCATOR_DM_TYPE, "true");
    assertEquals(null, OffHeapStorage.createOffHeapStorage(null, 1, null));
  }

  @Test
  public void createOffHeapStorageReturnsNullIfMemorySizeIsZero() {
    assertEquals(null, OffHeapStorage.createOffHeapStorage(null, 0, null));
  }

  @Test
  public void exceptionIfSlabCountTooSmall() {
    StatisticsFactory statsFactory = mock(StatisticsFactory.class);
    try {
      OffHeapStorage.createOffHeapStorage(statsFactory, OffHeapStorage.MIN_SLAB_SIZE - 1, null);
    } catch (IllegalArgumentException expected) {
      expected.getMessage()
          .equals("The amount of off heap memory must be at least " + OffHeapStorage.MIN_SLAB_SIZE
              + " but it was set to " + (OffHeapStorage.MIN_SLAB_SIZE - 1));
    }
  }

  @Test
  public void exceptionIfDistributedSystemNull() {
    StatisticsFactory statsFactory = mock(StatisticsFactory.class);
    try {
      OffHeapStorage.createOffHeapStorage(statsFactory, OffHeapStorage.MIN_SLAB_SIZE,
          null);
    } catch (IllegalArgumentException expected) {
      expected.getMessage().equals("InternalDistributedSystem is null");
    }
  }

  @Test
  public void createOffHeapStorageWorks() {
    StatisticsFactory localStatsFactory = new LocalStatisticsFactory(null);
    InternalDistributedSystem ids = mock(InternalDistributedSystem.class);
    MemoryAllocator ma =
        OffHeapStorage.createOffHeapStorage(localStatsFactory, OffHeapStorage.MIN_SLAB_SIZE, ids);
    System.setProperty(MemoryAllocatorImpl.FREE_OFF_HEAP_MEMORY_PROPERTY, "true");
    ma.close();
  }

  @Test
  public void testCreateOffHeapStorage() {
    StatisticsFactory localStatsFactory = new LocalStatisticsFactory(null);
    OutOfOffHeapMemoryListener ooohml = mock(OutOfOffHeapMemoryListener.class);
    MemoryAllocator ma =
        OffHeapStorage.basicCreateOffHeapStorage(localStatsFactory, 1024 * 1024, ooohml, null,
            () -> new DummyNonRealTimeStatsUpdater());
    try {
      OffHeapMemoryStats stats = ma.getStats();
      assertNotNull(stats.getStats());
      assertEquals(1024 * 1024, stats.getFreeMemory());
      assertEquals(1024 * 1024, stats.getMaxMemory());
      assertEquals(0, stats.getUsedMemory());
      assertEquals(0, stats.getDefragmentations());
      assertEquals(0, stats.getDefragmentationsInProgress());
      assertEquals(0, stats.getDefragmentationTime());
      assertEquals(0, stats.getFragmentation());
      assertEquals(1, stats.getFragments());
      assertEquals(1024 * 1024, stats.getLargestFragment());
      assertEquals(0, stats.getObjects());
      assertEquals(0, stats.getReads());

      stats.incFreeMemory(100);
      assertEquals(1024 * 1024 + 100, stats.getFreeMemory());
      stats.incFreeMemory(-100);
      assertEquals(1024 * 1024, stats.getFreeMemory());

      stats.incMaxMemory(100);
      assertEquals(1024 * 1024 + 100, stats.getMaxMemory());
      stats.incMaxMemory(-100);
      assertEquals(1024 * 1024, stats.getMaxMemory());

      stats.incUsedMemory(100);
      assertEquals(100, stats.getUsedMemory());
      stats.incUsedMemory(-100);
      assertEquals(0, stats.getUsedMemory());

      stats.incObjects(100);
      assertEquals(100, stats.getObjects());
      stats.incObjects(-100);
      assertEquals(0, stats.getObjects());

      stats.incReads();
      assertEquals(1, stats.getReads());

      stats.setFragmentation(100);
      assertEquals(100, stats.getFragmentation());
      stats.setFragmentation(0);
      assertEquals(0, stats.getFragmentation());

      stats.setFragments(2);
      assertEquals(2, stats.getFragments());
      stats.setFragments(1);
      assertEquals(1, stats.getFragments());

      stats.setLargestFragment(100);
      assertEquals(100, stats.getLargestFragment());
      stats.setLargestFragment(1024 * 1024);
      assertEquals(1024 * 1024, stats.getLargestFragment());

      boolean originalEnableClockStats = DistributionStats.enableClockStats;
      DistributionStats.enableClockStats = true;
      try {
        long start = stats.startDefragmentation();
        assertEquals(1, stats.getDefragmentationsInProgress());
        while (DistributionStats.getStatTime() == start) {
          Thread.yield();
        }
        stats.endDefragmentation(start);
        assertEquals(1, stats.getDefragmentations());
        assertEquals(0, stats.getDefragmentationsInProgress());
        assertTrue(stats.getDefragmentationTime() > 0);
      } finally {
        DistributionStats.enableClockStats = originalEnableClockStats;
      }

      stats.incObjects(100);
      stats.incUsedMemory(100);
      stats.setFragmentation(100);
      OffHeapStorage ohs = (OffHeapStorage) stats;
      ohs.initialize(new NullOffHeapMemoryStats());
      assertEquals(0, stats.getFreeMemory());
      assertEquals(0, stats.getMaxMemory());
      assertEquals(0, stats.getUsedMemory());
      assertEquals(0, stats.getDefragmentations());
      assertEquals(0, stats.getDefragmentationsInProgress());
      assertEquals(0, stats.getDefragmentationTime());
      assertEquals(0, stats.getFragmentation());
      assertEquals(0, stats.getFragments());
      assertEquals(0, stats.getLargestFragment());
      assertEquals(0, stats.getObjects());
      assertEquals(0, stats.getReads());

      OutOfOffHeapMemoryException ex = null;
      try {
        ma.allocate(1024 * 1024 + 1);
        fail("expected OutOfOffHeapMemoryException");
      } catch (OutOfOffHeapMemoryException expected) {
        ex = expected;
      }
      verify(ooohml).outOfOffHeapMemory(ex);
      try {
        ma.allocate(1024 * 1024 + 1);
        fail("expected OutOfOffHeapMemoryException");
      } catch (OutOfOffHeapMemoryException expected) {
        ex = expected;
      }
      verify(ooohml).outOfOffHeapMemory(ex);

    } finally {
      System.setProperty(MemoryAllocatorImpl.FREE_OFF_HEAP_MEMORY_PROPERTY, "true");
      try {
        ma.close();
      } finally {
        System.clearProperty(MemoryAllocatorImpl.FREE_OFF_HEAP_MEMORY_PROPERTY);
      }
    }
  }

  @Test
  public void testCalcSlabCount() {
    final long MSS = OffHeapStorage.MIN_SLAB_SIZE;
    assertEquals(100, OffHeapStorage.calcSlabCount(MSS * 4, MSS * 4 * 100));
    assertEquals(100, OffHeapStorage.calcSlabCount(MSS * 4, (MSS * 4 * 100) + (MSS - 1)));
    assertEquals(101, OffHeapStorage.calcSlabCount(MSS * 4, (MSS * 4 * 100) + MSS));
    assertEquals(Integer.MAX_VALUE, OffHeapStorage.calcSlabCount(MSS, MSS * Integer.MAX_VALUE));
    assertEquals(Integer.MAX_VALUE,
        OffHeapStorage.calcSlabCount(MSS, (MSS * Integer.MAX_VALUE) + MSS - 1));
    try {
      OffHeapStorage.calcSlabCount(MSS, (MSS * Integer.MAX_VALUE) + MSS);
      fail("Expected IllegalArgumentException");
    } catch (IllegalArgumentException expected) {
    }
  }
}
