/*
 * 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.internal.statistics.StatisticsClockFactory.disabledClock;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

import java.util.Properties;

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

import org.apache.geode.cache.AttributesFactory;
import org.apache.geode.cache.CacheFactory;
import org.apache.geode.cache.DataPolicy;
import org.apache.geode.cache.Region;
import org.apache.geode.cache.Scope;
import org.apache.geode.distributed.DistributedSystem;
import org.apache.geode.internal.cache.EventID;
import org.apache.geode.internal.cache.GemFireCacheImpl;
import org.apache.geode.internal.cache.HARegion;
import org.apache.geode.internal.cache.InternalCache;
import org.apache.geode.test.dunit.Host;
import org.apache.geode.test.dunit.VM;
import org.apache.geode.test.dunit.internal.JUnit4DistributedTestCase;
import org.apache.geode.test.junit.categories.ClientSubscriptionTest;

/**
 * Test to verify :
 *
 * 1)put() on a mirrored HARegion does not propagate 2)localDestroy() allowed on a mirrored region
 * 3) GII happens normally
 */
@Category({ClientSubscriptionTest.class})
public class HARegionDUnitTest extends JUnit4DistributedTestCase {

  VM vm0 = null;

  VM vm1 = null;

  private static InternalCache cache = null;
  private static final String REGION_NAME = "HARegionDUnitTest_region";

  /** constructor */
  public HARegionDUnitTest() {
    super();
  }

  /**
   * get the VM's
   */
  @Override
  public final void postSetUp() throws Exception {
    final Host host = Host.getHost(0);
    vm0 = host.getVM(0);
    vm1 = host.getVM(1);
  }

  /**
   * close the cache in tearDown
   */
  @Override
  public final void preTearDown() throws Exception {
    vm0.invoke(() -> HARegionDUnitTest.closeCache());
    vm1.invoke(() -> HARegionDUnitTest.closeCache());
  }

  /**
   * create cache
   *
   */
  private InternalCache createCache() throws Exception {
    Properties props = new Properties();
    DistributedSystem ds = getSystem(props);
    ds.disconnect();
    ds = getSystem(props);
    InternalCache cache = null;
    cache = (InternalCache) CacheFactory.create(ds);
    if (cache == null) {
      throw new Exception("CacheFactory.create() returned null ");
    }
    return cache;
  }

  /**
   * 1) Create mirrored HARegion region1 in VM1 and VM2 2) do a put in VM1 3) assert that the put
   * has not propagated from VM1 to VM2 4) do a put in VM2 5) assert that the value in VM1 has not
   * changed to due to put in VM2 6) assert put in VM2 was successful by doing a get
   *
   */
  @Test
  public void testLocalPut() {
    vm0.invoke(() -> HARegionDUnitTest.createRegion());
    vm1.invoke(() -> HARegionDUnitTest.createRegion());
    vm0.invoke(() -> HARegionDUnitTest.putValue1());
    vm1.invoke(() -> HARegionDUnitTest.getNull());
    vm1.invoke(() -> HARegionDUnitTest.putValue2());
    vm0.invoke(() -> HARegionDUnitTest.getValue1());
    vm1.invoke(() -> HARegionDUnitTest.getValue2());

  }

  /**
   * 1) Create mirrored HARegion region1 in VM1 and VM2 2) do a put in VM1 3) assert that the put
   * has not propagated from VM1 to VM2 4) do a put in VM2 5) assert that the value in VM1 has not
   * changed to due to put in VM2 6) assert respective puts the VMs were successful by doing a get
   * 7) localDestroy key in VM1 8) assert key has been destroyed in VM1 9) assert key has not been
   * destroyed in VM2
   *
   */
  @Test
  public void testLocalDestroy() {
    vm0.invoke(() -> HARegionDUnitTest.createRegion());
    vm1.invoke(() -> HARegionDUnitTest.createRegion());
    vm0.invoke(() -> HARegionDUnitTest.putValue1());
    vm1.invoke(() -> HARegionDUnitTest.getNull());
    vm1.invoke(() -> HARegionDUnitTest.putValue2());
    vm0.invoke(() -> HARegionDUnitTest.getValue1());
    vm1.invoke(() -> HARegionDUnitTest.getValue2());
    vm0.invoke(() -> HARegionDUnitTest.destroy());
    vm0.invoke(() -> HARegionDUnitTest.getNull());
    vm1.invoke(() -> HARegionDUnitTest.getValue2());
  }

  /**
   * 1) Create mirrored HARegion region1 in VM1 2) do a put in VM1 3) get the value in VM1 to assert
   * put has happened successfully 4) Create mirrored HARegion region1 in VM2 5) do a get in VM2 to
   * verify that value was got through GII 6) do a put in VM2 7) assert put in VM2 was successful
   *
   */
  @Test
  public void testGII() {
    vm0.invoke(() -> HARegionDUnitTest.createRegion());
    vm0.invoke(() -> HARegionDUnitTest.putValue1());
    vm0.invoke(() -> HARegionDUnitTest.getValue1());
    vm1.invoke(() -> HARegionDUnitTest.createRegion());
    vm1.invoke(() -> HARegionDUnitTest.getValue1());
    vm1.invoke(() -> HARegionDUnitTest.putValue2());
    vm1.invoke(() -> HARegionDUnitTest.getValue2());

  }

  /**
   * 1) Create mirrored HARegion region1 in VM1 2) do a put in VM1 3) get the value in VM1 to assert
   * put has happened successfully 4) Create mirrored HARegion region1 in VM2 5) do a get in VM2 to
   * verify that value was got through GII 6) do a put in VM2 7) assert put in VM2 was successful
   *
   */
  @Test
  public void testLocalDestroyRegion() {
    vm0.invoke(() -> HARegionDUnitTest.createRegion());
    vm1.invoke(() -> HARegionDUnitTest.createRegion());
    vm0.invoke(() -> HARegionDUnitTest.destroyRegion());
    vm1.invoke(() -> HARegionDUnitTest.verifyRegionNotDestroyed());

  }

  /**
   * Destroy the region
   *
   */
  public static void destroyRegion() {
    cache.getRegion(REGION_NAME).localDestroyRegion(null);
  }

  /**
   * Verify Region exists
   *
   */
  public static void verifyRegionNotDestroyed() {
    assertTrue(cache.getRegion(REGION_NAME) != null);
  }

  /**
   * 1) Create mirrored HARegion region1 in VM1 2) do a put in VM1 3) get the value in VM1 to assert
   * put has happened successfully 4) Create mirrored HARegion region1 in VM2 5) do a get in VM2 to
   * verify that value was got through GII 6) do a put in VM2 7) assert put in VM2 was successful
   *
   */
  @Test
  public void testQRM() {
    vm0.invoke(() -> HARegionDUnitTest.createRegionQueue());
    vm1.invoke(() -> HARegionDUnitTest.createRegionQueue());
    vm0.invoke(() -> HARegionDUnitTest.verifyAddingDispatchMesgs());
    try {
      Thread.sleep(5000);
    } catch (InterruptedException e) {
      fail("interrupted");
    }
    vm1.invoke(() -> HARegionDUnitTest.verifyDispatchedMessagesRemoved());
  }

  /**
   * create a client with 2 regions sharing a common writer
   *
   */

  public static void createRegion() throws Exception {
    HARegionDUnitTest test = new HARegionDUnitTest();
    cache = test.createCache();
    AttributesFactory factory = new AttributesFactory();
    factory.setScope(Scope.DISTRIBUTED_ACK);
    factory.setDataPolicy(DataPolicy.REPLICATE);

    // Mock the HARegionQueue and answer the input CachedDeserializable when updateHAEventWrapper is
    // called
    HARegionQueue harq = mock(HARegionQueue.class);
    when(harq.updateHAEventWrapper(any(), any(), any()))
        .thenAnswer(AdditionalAnswers.returnsSecondArg());

    HARegion.getInstance(REGION_NAME, (GemFireCacheImpl) cache, harq, factory.create(),
        disabledClock());
  }

  private static HARegionQueue hrq = null;

  // private static int counter = 0;

  public static void createRegionQueue() throws Exception {
    HARegionDUnitTest test = new HARegionDUnitTest();
    cache = test.createCache();
    /*
     * AttributesFactory factory = new AttributesFactory(); factory.setScope(Scope.DISTRIBUTED_ACK);
     * factory.setDataPolicy(DataPolicy.REPLICATE);
     */
    hrq = HARegionQueue.getHARegionQueueInstance(REGION_NAME, cache,
        HARegionQueue.NON_BLOCKING_HA_QUEUE, false, disabledClock());
    EventID id1 = new EventID(new byte[] {1}, 1, 1);
    EventID id2 = new EventID(new byte[] {1}, 1, 2);
    ConflatableObject c1 = new ConflatableObject("1", "1", id1, false, REGION_NAME);
    ConflatableObject c2 = new ConflatableObject("2", "2", id2, false, REGION_NAME);
    hrq.put(c1);
    hrq.put(c2);

  }

  public static void verifyAddingDispatchMesgs() {
    assertTrue(HARegionQueue.getDispatchedMessagesMapForTesting().isEmpty());
    hrq.addDispatchedMessage(new ThreadIdentifier(new byte[1], 1), 1);
    assertTrue(!HARegionQueue.getDispatchedMessagesMapForTesting().isEmpty());
  }



  public static void verifyDispatchedMessagesRemoved() {
    try {
      Region region = hrq.getRegion();
      if (region.get(new Long(0)) != null) {
        fail("Expected message to have been deleted but it is not deleted");
      }

      if (region.get(new Long(1)) == null) {
        fail("Expected message not to have been deleted but it is deleted");
      }
    } catch (Exception e) {
      fail("test failed due to an exception :  " + e);
    }
  }

  /**
   * close the cache
   *
   */
  public static void closeCache() {
    if (cache != null && !cache.isClosed()) {
      cache.close();
      cache.getDistributedSystem().disconnect();
    }
  }

  /**
   * do three puts on key-1
   *
   */
  public static void putValue1() {
    try {
      Region r1 = cache.getRegion(Region.SEPARATOR + REGION_NAME);
      r1.put("key-1", "value-1");
    } catch (Exception ex) {
      ex.printStackTrace();
      org.apache.geode.test.dunit.Assert.fail("failed while region.put()", ex);
    }
  }

  /**
   * do three puts on key-1
   *
   */
  public static void putValue2() {
    try {
      Region r1 = cache.getRegion(Region.SEPARATOR + REGION_NAME);
      r1.put("key-1", "value-2");
    } catch (Exception ex) {
      ex.printStackTrace();
      org.apache.geode.test.dunit.Assert.fail("failed while region.put()", ex);
    }
  }

  /**
   * do a get on region1
   *
   */
  public static void getValue1() {
    try {
      Region r = cache.getRegion(Region.SEPARATOR + REGION_NAME);
      if (!(r.get("key-1").equals("value-1"))) {
        fail("expected value to be value-1 but it is not so");
      }

    } catch (Exception ex) {
      ex.printStackTrace();
      org.apache.geode.test.dunit.Assert.fail("failed while region.get()", ex);
    }
  }

  /**
   * do a get on region1
   *
   */
  public static void getNull() {
    try {
      Region r = cache.getRegion(Region.SEPARATOR + REGION_NAME);
      if (!(r.get("key-1") == (null))) {
        fail("expected value to be null but it is not so");
      }

    } catch (Exception ex) {
      ex.printStackTrace();
      org.apache.geode.test.dunit.Assert.fail("failed while region.get()", ex);
    }
  }

  /**
   * do a get on region1
   *
   */
  public static void getValue2() {
    try {
      Region r = cache.getRegion(Region.SEPARATOR + REGION_NAME);
      if (!(r.get("key-1").equals("value-2"))) {
        fail("expected value to be value-2 but it is not so");
      }

    } catch (Exception ex) {
      ex.printStackTrace();
      org.apache.geode.test.dunit.Assert.fail("failed while region.get()", ex);
    }
  }

  /**
   * destroy key-1
   *
   */
  public static void destroy() {
    try {
      Region region1 = cache.getRegion(Region.SEPARATOR + REGION_NAME);
      region1.localDestroy("key-1");
    } catch (Exception e) {
      e.printStackTrace();
      fail("test failed due to exception in destroy ");
    }
  }

}
