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

import static org.apache.geode.distributed.ConfigurationProperties.MCAST_PORT;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;

import java.io.IOException;

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

import org.apache.geode.cache.AttributesFactory;
import org.apache.geode.cache.CacheException;
import org.apache.geode.cache.CacheFactory;
import org.apache.geode.cache.DataPolicy;
import org.apache.geode.cache.Scope;
import org.apache.geode.internal.cache.Conflatable;
import org.apache.geode.internal.cache.EventID;
import org.apache.geode.internal.cache.InternalCache;
import org.apache.geode.test.junit.categories.ClientSubscriptionTest;

/**
 * JUnit test for verifying the proper functioning of HARegionQueue related statistics.
 *
 *
 */
@Category({ClientSubscriptionTest.class})
public class HARegionQueueStatsJUnitTest {

  /** The cache instance */
  protected InternalCache cache = null;

  /**
   * Create the cache in setup. Currently the HA related stats are active under fine logging only.
   *
   * @throws Exception - thrown if any exception occurs in setUp
   */
  @Before
  public void setUp() throws Exception {
    cache = createCache();
  }

  /**
   * Close the cache in tear down *
   *
   * @throws Exception - thrown if any exception occurs in tearDown
   */
  @After
  public void tearDown() throws Exception {
    cache.close();
  }

  /**
   * Creates the cache instance for the test
   *
   * @return the cache instance
   * @throws CacheException - thrown if any exception occurs in cache creation
   */
  private InternalCache createCache() throws CacheException {
    return (InternalCache) new CacheFactory().set(MCAST_PORT, "0").create();
  }

  /**
   * Creates a HARegionQueue object.
   *
   * @param name - name of the underlying region for region-queue
   * @return the HARegionQueue instance
   */
  protected HARegionQueue createHARegionQueue(String name)
      throws IOException, ClassNotFoundException, CacheException, InterruptedException {
    HARegionQueue regionqueue = HARegionQueue.getHARegionQueueInstance(name, cache,
        HARegionQueue.NON_BLOCKING_HA_QUEUE, false);
    return regionqueue;
  }

  /**
   * Creates a HARegionQueue object.
   *
   * @param name - name of the underlying region for region-queue
   * @param attrs - attributes for the HARegionQueue
   * @return the HARegionQueue instance
   */
  protected HARegionQueue createHARegionQueue(String name, HARegionQueueAttributes attrs)
      throws IOException, ClassNotFoundException, CacheException, InterruptedException {
    AttributesFactory factory = new AttributesFactory();
    factory.setDataPolicy(DataPolicy.REPLICATE);
    factory.setScope(Scope.DISTRIBUTED_ACK);
    HARegionQueue regionqueue = HARegionQueue.getHARegionQueueInstance(name, cache, attrs,
        HARegionQueue.NON_BLOCKING_HA_QUEUE, false);
    return regionqueue;
  }

  /**
   * This test does the following:<br>
   * 1)Create HARegionQueue<br>
   * 2)Add objects with unique eventids and conflation false <br>
   * 3)Verify that statistics object is not null<br>
   * 4)Verify that total events added matches the eventsEnqued stats<br>
   * 5)Verify that eventsConflated stats is zero.
   *
   * @throws Exception - thrown if any problem occurs in test execution
   */
  @Test
  public void testPutStatsNoConflation() throws Exception {

    HARegionQueue rq = createHARegionQueue("testPutStatsNoConflation");
    Conflatable cf = null;

    int totalEvents = 100;
    for (int i = 0; i < totalEvents; i++) {
      cf = new ConflatableObject("key" + i, "value" + i, new EventID(new byte[] {1}, 1, i), false,
          "testing");
      rq.put(cf);
    }

    HARegionQueueStats stats = rq.getStatistics();
    assertNotNull("stats for HARegionQueue found null", stats);

    assertEquals(
        "eventsEnqued by stats not equal to the actual number of events added to the queue",
        totalEvents, stats.getEventsEnqued());

    assertEquals("eventsConflated by stats not equal zero", 0, stats.getEventsConflated());
  }

  /**
   * This test does the following:<br>
   * 1)Create HARegionQueue<br>
   * 2)Add objects with unique eventids and conflation true with same Key. <br>
   * 3)Verify that statistics object is not null<br>
   * 4)Verify that total events added matches the eventsEnqued stats<br>
   * 5)Verify that eventsConflated stats is total events added minus 1.
   *
   * @throws Exception - thrown if any problem occurs in test execution
   */
  @Test
  public void testPutStatsConflationEnabled() throws Exception {

    HARegionQueue rq = createHARegionQueue("testPutStatsConflationEnabled");
    Conflatable cf = null;

    int totalEvents = 100;
    for (int i = 0; i < totalEvents; i++) {
      cf = new ConflatableObject("key", "value" + i, new EventID(new byte[] {1}, 1, i), true,
          "testing");
      rq.put(cf);
    }

    HARegionQueueStats stats = rq.getStatistics();
    assertNotNull("stats for HARegionQueue found null", stats);

    assertEquals(
        "eventsEnqued by stats not equal to the actual number of events added to the queue",
        totalEvents, stats.getEventsEnqued());

    assertEquals("stats for eventsConflated mismatched", totalEvents - 1,
        stats.getEventsConflated());
  }

  /**
   * This test does the following:<br>
   * 1)Create HARegionQueue with expiry time as 1 sec<br>
   * 2)Add objects with unique eventids and conflation false and sleep for some time.<br>
   * 3)Verify that statistics object is not null<br>
   * 4)Verify that total events added matches the eventsEnqued stats<br>
   * 5)Verify that eventsExpired stats is same as total events added as all events should have
   * expired by 1 sec.
   *
   * @throws Exception - thrown if any problem occurs in test execution
   */
  @Test
  public void testExpiryStats() throws Exception {

    HARegionQueueAttributes haa = new HARegionQueueAttributes();
    haa.setExpiryTime(1);
    HARegionQueue rq = createHARegionQueue("testExpiryStats", haa);

    Conflatable cf = null;
    int totalEvents = 100;
    for (int i = 0; i < totalEvents; i++) {
      cf = new ConflatableObject("key" + i, "value" + i, new EventID(new byte[] {1}, 1, i), false,
          "testing");
      rq.put(cf);
    }

    Thread.sleep(3000);

    HARegionQueueStats stats = rq.stats;
    assertNotNull("stats for HARegionQueue found null", stats);
    assertEquals(
        "eventsEnqued by stats not equal to the actual number of events added to the queue",
        totalEvents, stats.getEventsEnqued());
    assertEquals("expiredEvents not updated", totalEvents, stats.getEventsExpired());
  }

  /**
   * This test does the following:<br>
   * 1)Create HARegionQueue.<br>
   * 2)Add objects with unique eventids and conflation false<br>
   * 3)Do some random peek and peek-batch operations and then call remove()<br>
   * 4)Verify that statistics object is not null<br>
   * 5)Verify that total events added matches the eventsEnqued stats<br>
   * 6)Verify that eventsRemoved stats is same as the maximum batch size peeked in above peek
   * operations(step 3).
   *
   * @throws Exception - thrown if any problem occurs in test execution
   */
  @Test
  public void testRemoveStats() throws Exception {
    HARegionQueue rq = createHARegionQueue("testRemoveStats");
    Conflatable cf = null;

    int totalEvents = 100;
    for (int i = 0; i < totalEvents; i++) {
      cf = new ConflatableObject("key" + i, "value" + i, new EventID(new byte[] {1}, 1, i), false,
          "testing");
      rq.put(cf);
    }

    // do some random peek operations.
    int maxPeekBatchSize = 50;
    rq.peek();
    rq.peek(8);
    rq.peek(maxPeekBatchSize);
    rq.peek(35);
    rq.peek();

    rq.remove();

    HARegionQueueStats stats = rq.getStatistics();
    assertNotNull("stats for HARegionQueue found null", stats);

    assertEquals(
        "eventsEnqued by stats not equal to the actual number of events added to the queue",
        totalEvents, stats.getEventsEnqued());

    assertEquals("All the events peeked were not removed", maxPeekBatchSize,
        stats.getEventsRemoved());
  }

  /**
   * This test does the following:<br>
   * 1)Create HARegionQueue.<br>
   * 2)Add objects with unique eventids and conflation false<br>
   * 3)Do some take and take-batch operations.<br>
   * 4)Verify that statistics object is not null<br>
   * 5)Verify that total events added matches the eventsEnqued stats<br>
   * 6)Verify that eventsTaken stats is same as the sum of events taken in batch and individually
   * (Step 3)
   *
   * @throws Exception - thrown if any problem occurs in test execution
   */
  @Test
  public void testTakeStats() throws Exception {
    HARegionQueue rq = createHARegionQueue("testTakeStats");
    Conflatable cf = null;

    int totalEvents = 100;
    for (int i = 0; i < totalEvents; i++) {
      cf = new ConflatableObject("key" + i, "value" + i, new EventID(new byte[] {1}, 1, i), false,
          "testing");
      rq.put(cf);
    }

    int takeInBatch = 50;
    int takeOneByOne = 25;
    rq.take(takeInBatch);
    for (int i = 0; i < takeOneByOne; i++) {
      rq.take();
    }

    HARegionQueueStats stats = rq.getStatistics();
    assertNotNull("stats for HARegionQueue found null", stats);

    assertEquals(
        "eventsEnqued by stats not equal to the actual number of events added to the queue",
        totalEvents, stats.getEventsEnqued());

    assertEquals("eventsTaken stats not matching with actual events taken",
        (takeInBatch + takeOneByOne), stats.getEventsTaken());
  }

  /**
   * This test does the following:<br>
   * 1)Create HARegionQueue.<br>
   * 2)Add objects with unique eventids and conflation false<br>
   * 3)Remove the events through QRM api ( <code>removeDispatchedEvents(EventID id)</code>) with a
   * certain lastDispatchedSeqId<br>
   * 4)Verify that statistics object is not null<br>
   * 5)Verify that total events added matches the eventsEnqued stats<br>
   * 6)Verify that eventsRemovedByQrm stats is same as the number of events removed by QRM (upto the
   * event having lastDispatchedSeqId, step 3).
   *
   * @throws Exception - thrown if any problem occurs in test execution
   */
  @Test
  public void testRemoveByQrmStats() throws Exception {
    HARegionQueue rq = createHARegionQueue("testRemoveByQrmStats");
    Conflatable cf = null;

    int totalEvents = 100;
    for (int i = 0; i < totalEvents; i++) {
      cf = new ConflatableObject("key" + i, "value" + i, new EventID(new byte[] {1}, 1, i), false,
          "testing");
      rq.put(cf);
    }

    // call for removal thru QRM api
    int lastDispatchedSqId = 20;
    EventID id = new EventID(new byte[] {1}, 1, lastDispatchedSqId);
    rq.removeDispatchedEvents(id);

    HARegionQueueStats stats = rq.getStatistics();
    assertNotNull("stats for HARegionQueue found null", stats);

    assertEquals(
        "eventsEnqued by stats not equal to the actual number of events added to the queue",
        totalEvents, stats.getEventsEnqued());
    assertEquals("eventsRemovedByQrm stats not updated properly", (lastDispatchedSqId + 1),
        stats.getEventsRemovedByQrm());

  }

  /**
   * This test does the following:<br>
   * 1)Create HARegionQueue.<br>
   * 2)Add objects with unique eventids as well as ThreadIDs and conflation false<br>
   * 3)Verify that statistics object is not null<br>
   * 4)Verify that total events added matches the eventsEnqued stats<br>
   * 5)Verify that threadIdentifiers stats is same as the number of events added as all the events
   * had different ThreadIdentifier objects.
   *
   * @throws Exception - thrown if any problem occurs in test execution
   */
  @Test
  public void testThreadIdentifierStats() throws Exception {
    HARegionQueue rq = createHARegionQueue("testRemoveByQrmStats");
    Conflatable cf = null;

    int totalEvents = 100;
    for (int i = 0; i < totalEvents; i++) {
      cf = new ConflatableObject("key" + i, "value" + i, new EventID(new byte[] {1}, i, i), false,
          "testing");
      rq.put(cf);
    }

    HARegionQueueStats stats = rq.getStatistics();
    assertNotNull("stats for HARegionQueue found null", stats);

    assertEquals(
        "eventsEnqued by stats not equal to the actual number of events added to the queue",
        totalEvents, stats.getEventsEnqued());
    assertEquals("threadIdentifiers stats not updated properly", totalEvents,
        stats.getThreadIdentiferCount());

  }

  /**
   * This test does the following:<br>
   * 1)Create HARegionQueue.<br>
   * 2)Add objects with unique eventids and conflation false<br>
   * 3)peek a batch to peek all the events added and take() all the events<br>
   * 4)Call remove()<br>
   * 5)Verify that statistics object is not null<br>
   * 6)Verify that total events added matches the eventsEnqued stats<br>
   * 7)Verify that numVoidRemovals stats is same as the total events added since all the peeked
   * events were removed by take() call and remove() was a void operation.
   *
   * @throws Exception - thrown if any problem occurs in test execution
   */
  @Test
  public void testVoidRemovalStats() throws Exception {
    HARegionQueue rq = createHARegionQueue("testVoidRemovalStats");
    Conflatable cf = null;

    int totalEvents = 100;
    for (int i = 0; i < totalEvents; i++) {
      cf = new ConflatableObject("key" + i, "value" + i, new EventID(new byte[] {1}, 1, i), false,
          "testing");
      rq.put(cf);
    }

    rq.peek(totalEvents);
    rq.take(totalEvents);
    rq.remove();

    HARegionQueueStats stats = rq.getStatistics();
    assertNotNull("stats for HARegionQueue found null", stats);

    assertEquals(
        "eventsEnqued by stats not equal to the actual number of events added to the queue",
        totalEvents, stats.getEventsEnqued());

    assertEquals(
        "Number of void removals shud be equal to total peeked since all the events were removed by take() before remove()",
        totalEvents, stats.getNumVoidRemovals());
  }

  /**
   * This test does the follwing: <br>
   * 1)Create HARegionQueue.<br>
   * 2)Add objects with unique eventids and conflation false.<br>
   * 3)Add some objects with same eventids(sequence ids)- duplicate events.<br>
   * 4)Verify that numSequenceViolated stats is same as number of duplicate events.<br>
   * 5)Verify that eventsEnqued stats is same as the queue size ( i.e. eventsEnqued stats is not
   * updated for duplicate events.)
   *
   */
  @Test
  public void testSequenceViolationStats() throws Exception {
    HARegionQueue rq = createHARegionQueue("testSequenceViolationStats");
    Conflatable cf = null;

    int totalEvents = 10;
    for (int i = 0; i < totalEvents; i++) {
      cf = new ConflatableObject("key" + i, "value" + i, new EventID(new byte[] {1}, 1, i), false,
          "testing");
      rq.put(cf);
    }

    int seqViolated = 3;
    for (int i = 0; i < seqViolated; i++) {
      cf = new ConflatableObject("key" + i, "value" + i, new EventID(new byte[] {1}, 1, i), false,
          "testing");
      rq.put(cf);
    }

    HARegionQueueStats stats = rq.getStatistics();
    assertNotNull("stats for HARegionQueue found null", stats);

    assertEquals("Number of sequence violated by stats not equal to the actual number", seqViolated,
        stats.getNumSequenceViolated());
    assertEquals(
        "Events corresponding to sequence violation not added to the queue but eventsEnqued stats updated for them.",
        rq.size(), stats.getEventsEnqued());
  }


}
