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

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.junit.Before;
import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.runners.MethodSorters;

import org.apache.geode.LogWriter;
import org.apache.geode.cache.AttributesFactory;
import org.apache.geode.cache.Cache;
import org.apache.geode.cache.DataPolicy;
import org.apache.geode.cache.PartitionAttributesFactory;
import org.apache.geode.cache.Region;
import org.apache.geode.cache.RegionAttributes;
import org.apache.geode.cache.RegionExistsException;
import org.apache.geode.cache.Scope;

/**
 * This is a test for creation of Partition region(PR).
 * <p>
 * Following tests are included in PartitionedRegionCreationJUnitTest :
 * </p>
 * <p>
 * 1) testpartionedRegionCreate - Tests the PR creation.
 * </p>
 * <p>
 * 2) testpartionedRegionInitialization - Tests the PR initialization
 * </p>
 * <p>
 * 3) testpartionedRegionRegistration - Tests the PR registration
 * </p>
 * <p>
 * 4) testpartionedRegionBucketToNodeCreate - Tests the PR's BUCKET_2_NODE region creation
 * </p>
 *
 *
 */
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class PartitionedRegionCreationJUnitTest {
  static volatile int PRNumber = 0;

  static Region root = null;

  static volatile boolean increamentFlag = false;

  static final int TOTAL_THREADS = 10;

  static volatile int TOTAL_PR_CREATED = 0;

  static volatile int TOTAL_RETURNS = 0;

  static volatile int TOTAL_PR_CREATION_FAIL = 0;

  static final Object PR_CREATE = new Object();

  static final Object PR_CREATE_FAIL = new Object();

  static final Object PR_INCREMENT = new Object();

  static final Object PR_TOTAL_RETURNS = new Object();

  public boolean PRCreateDone = false;

  List PRRegionList = new ArrayList();

  LogWriter logger = null;

  private Object CREATE_COMPLETE_LOCK = new Object();

  private volatile boolean createComplete = false;

  @Before
  public void setUp() throws Exception {
    TOTAL_RETURNS = 0;
    if (logger == null)
      logger = PartitionedRegionTestHelper.getLogger();
  }

  /*
   * 1)Create 10 thread each. Each thread will try to create PartionedRegion total of 5 partitioned
   * region will be created. 5 threads should throw RegionExistException. 2) Tests for PR scope =
   * GLOBAL and PR scope = LOCAL </p> 3) Test for redundancy < 0 </p> 4) Test for redundancy > 3
   * </p> 5) Test for localMaxMemory < 0 </p>
   */
  @Test
  public void test000PartitionedRegionCreate() {
    createMultiplePartitionedRegions();
    verifyCreateResults();
    if (logger.fineEnabled()) {
      logger.fine(
          " PartitionedRegionCreationTest-testpartionedRegionCreate() Successfully Complete ..  ");
    }

    final String regionname = "testPartionedRegionCreate";
    int localMaxMemory = 0;
    PartitionedRegion pr = null;

    // Test vanilla creation of a Partitioned Region w/o Scope
    try {
      AttributesFactory af = new AttributesFactory();
      af.setDataPolicy(DataPolicy.PARTITION);
      RegionAttributes ra = af.create();
      Cache cache = PartitionedRegionTestHelper.createCache();
      pr = (PartitionedRegion) cache.createRegion(regionname, ra);
    } finally {
      pr.destroyRegion();
    }

    // Assert that setting any scope throws IllegalStateException
    final Scope[] scopes =
        {Scope.LOCAL, Scope.DISTRIBUTED_ACK, Scope.DISTRIBUTED_NO_ACK, Scope.GLOBAL};
    for (int i = 0; i < scopes.length; i++) {
      try {
        AttributesFactory af = new AttributesFactory();
        af.setDataPolicy(DataPolicy.PARTITION);
        af.setScope(scopes[i]);
        RegionAttributes ra = af.create();
        Cache cache = PartitionedRegionTestHelper.createCache();
        pr = (PartitionedRegion) cache.createRegion(regionname, ra);
        fail("testpartionedRegionCreate() Expected IllegalStateException not thrown for Scope "
            + scopes[i]);
      } catch (IllegalStateException expected) {
      } finally {
        if (pr != null && !pr.isDestroyed()) {
          pr.destroyRegion();
        }
      }
    }

    // test for redundancy > 3
    int redundancy = 10;
    try {
      pr = (PartitionedRegion) PartitionedRegionTestHelper.createPartitionedRegion(regionname,
          String.valueOf(localMaxMemory), redundancy);
    } catch (IllegalStateException illex) {
      if (logger.fineEnabled()) {
        logger.fine(
            "testpartionedRegionCreate() Got a correct exception-IllegalStateException for  redundancy > 3 ");
      }
    }

    // test for redundancy < 0
    if (pr != null && !pr.isDestroyed())
      pr.destroyRegion();
    redundancy = -5;
    try {
      pr = (PartitionedRegion) PartitionedRegionTestHelper.createPartitionedRegion(regionname,
          String.valueOf(200), redundancy);
      fail(
          "testpartionedRegionCreate() Expected IllegalStateException not thrown for redundancy < 0 ");
    } catch (IllegalStateException illex) {
      if (logger.fineEnabled()) {
        logger.fine(
            "testpartionedRegionCreate() Got a correct exception-IllegalStateException for  redundancy < 0 ");
      }
    }

    // test for localMaxMemory < 0
    /*
     * if (pr!= null && !pr.isDestroyed()) pr.destroyRegion(); ; localMaxMemory = -5; try { pr =
     * (PartitionedRegion)PartitionedRegionTestHelper .createPartitionedRegion(regionname,
     * String.valueOf(localMaxMemory), 2, Scope.DISTRIBUTED_ACK);
     * fail("testpartionedRegionCreate() Expected IllegalStateException not thrown for localMaxMemory < 0 "
     * ); } catch (IllegalStateException illex) { if (logger.fineEnabled()) { logger
     * .fine("testpartionedRegionCreate() Got a correct exception-IllegalStateException for  localMaxMemory < 0  "
     * ); } }
     */
  }

  @Test
  public void test001PersistentPartitionedRegionCreate() {
    final String regionname = "testPersistentPartionedRegionCreate";
    PartitionedRegion pr = null;

    // Test vanilla creation of a Partitioned Region w/o Scope
    try {
      AttributesFactory af = new AttributesFactory();
      af.setDataPolicy(DataPolicy.PERSISTENT_PARTITION);
      RegionAttributes ra = af.create();
      Cache cache = PartitionedRegionTestHelper.createCache();
      pr = (PartitionedRegion) cache.createRegion(regionname, ra);
    } finally {
      if (pr != null) {
        pr.destroyRegion();
      }
    }

    // Assert that an accessor (localMaxMem == 0) can't be persistent
    try {
      AttributesFactory af = new AttributesFactory();
      af.setDataPolicy(DataPolicy.PERSISTENT_PARTITION);
      af.setPartitionAttributes(new PartitionAttributesFactory().setLocalMaxMemory(0).create());

      RegionAttributes ra = af.create();
      Cache cache = PartitionedRegionTestHelper.createCache();
      pr = (PartitionedRegion) cache.createRegion(regionname, ra);
      fail("testpartionedRegionCreate() Expected IllegalStateException not thrown");
    } catch (IllegalStateException expected) {
      assertEquals("Persistence is not allowed when local-max-memory is zero.",
          expected.getMessage());
    }

    // Assert that a region can't be created
    // if configured with a diskStoreName and the disk store has not be created.
    try {
      AttributesFactory af = new AttributesFactory();
      af.setDataPolicy(DataPolicy.PERSISTENT_PARTITION);
      af.setDiskStoreName("nonexistentDiskStore");
      RegionAttributes ra = af.create();
      Cache cache = PartitionedRegionTestHelper.createCache();
      pr = (PartitionedRegion) cache.createRegion(regionname, ra);
      fail("testpartionedRegionCreate() Expected IllegalStateException not thrown");
    } catch (RuntimeException expected) {
      assertTrue(expected.getMessage().contains(String.format("Disk store %s not found",
          "nonexistentDiskStore")));
    }

    // Assert that you can't have a diskStoreName unless you are persistent or overflow.
    try {
      Cache cache = PartitionedRegionTestHelper.createCache();
      cache.createDiskStoreFactory().create("existentDiskStore");
      AttributesFactory af = new AttributesFactory();
      af.setDataPolicy(DataPolicy.PARTITION);
      af.setDiskStoreName("existentDiskStore");
      RegionAttributes ra = af.create();
      pr = (PartitionedRegion) cache.createRegion(regionname, ra);
      fail("testpartionedRegionCreate() Expected IllegalStateException not thrown");
    } catch (IllegalStateException expected) {
      assertEquals("Only regions with persistence or overflow to disk can specify DiskStore",
          expected.getMessage());
    }

    // Assert that setting any scope throws IllegalStateException
    final Scope[] scopes =
        {Scope.LOCAL, Scope.DISTRIBUTED_ACK, Scope.DISTRIBUTED_NO_ACK, Scope.GLOBAL};
    for (int i = 0; i < scopes.length; i++) {
      try {
        AttributesFactory af = new AttributesFactory();
        af.setDataPolicy(DataPolicy.PERSISTENT_PARTITION);
        af.setScope(scopes[i]);
        RegionAttributes ra = af.create();
        Cache cache = PartitionedRegionTestHelper.createCache();
        pr = (PartitionedRegion) cache.createRegion(regionname, ra);
        fail("testpartionedRegionCreate() Expected IllegalStateException not thrown for Scope "
            + scopes[i]);
      } catch (IllegalStateException expected) {
      }
    }

    // test for redundancy > 3
    try {
      pr = (PartitionedRegion) PartitionedRegionTestHelper.createPartitionedRegion(regionname,
          String.valueOf(0), 4);
      fail(
          "testpartionedRegionCreate() Expected IllegalStateException not thrown for redundancy > 3 ");
    } catch (IllegalStateException illex) {
      if (logger.fineEnabled()) {
        logger.fine(
            "testpartionedRegionCreate() Got a correct exception-IllegalStateException for  redundancy > 3 ");
      }
    }

    // test for redundancy < 0
    try {
      pr = (PartitionedRegion) PartitionedRegionTestHelper.createPartitionedRegion(regionname,
          String.valueOf(200), -1);
      fail(
          "testpartionedRegionCreate() Expected IllegalStateException not thrown for redundancy < 0 ");
    } catch (IllegalStateException illex) {
      if (logger.fineEnabled()) {
        logger.fine(
            "testpartionedRegionCreate() Got a correct exception-IllegalStateException for  redundancy < 0 ");
      }
    }
  }

  /**
   * Test for initialization of PartitionedRegion. Following are tested for the PartitionedRegion:
   * <p>
   * (1) Test for Root == null
   * <p>
   * (2) Test for Root region scope is DIST_ACK
   * <p>
   * (3) Test if MirrorType.NONE for root region.
   * <p>
   * (4) Test if PARTITIONED_REGION_CONFIG_NAME exist and isDistributedAck and the mirror type is
   * MirrorType.KEYS_VALUES.
   *
   */
  @Test
  public void test002PartionedRegionInitialization() throws RegionExistsException {
    String PRName = "testpartionedRegionInitialization";
    PartitionedRegionTestHelper.createPartionedRegion(PRName);

    Region root = (PartitionedRegionTestHelper
        .getExistingRegion(PartitionedRegionHelper.PR_ROOT_REGION_NAME));
    if (root == null)
      fail("testpartionedRegionInitialization() - the "
          + PartitionedRegionHelper.PR_ROOT_REGION_NAME + " do not exists");
    RegionAttributes regionAttribs = root.getAttributes();
    Scope scope = regionAttribs.getScope();
    if (!scope.isDistributedAck())
      fail("testpartionedRegionInitialization() - the "
          + PartitionedRegionHelper.PR_ROOT_REGION_NAME + " scope is not distributed_ack");
    assertEquals(DataPolicy.REPLICATE, regionAttribs.getDataPolicy());

    // Region allPartitionedRegions = root
    // .getSubregion(PartitionedRegionHelper.PARTITIONED_REGION_CONFIG_NAME);
    // if (allPartitionedRegions == null)
    // fail("testpartionedRegionInitialization() - the "
    // + PartitionedRegionHelper.PARTITIONED_REGION_CONFIG_NAME
    // + " do not exists");
    //
    // regionAttribs = allPartitionedRegions.getAttributes();
    // scope = regionAttribs.getScope();
    // if (!scope.isDistributedAck())
    // fail("testpartionedRegionInitialization() - the "
    // + PartitionedRegionHelper.PARTITIONED_REGION_CONFIG_NAME
    // + " scope is not distributed_ack");
    // MirrorType mirrortype = regionAttribs.getMirrorType();
    // if (mirrortype != MirrorType.KEYS_VALUES)
    // fail("testpartionedRegionInitialization() - the "
    // + PartitionedRegionHelper.PARTITIONED_REGION_CONFIG_NAME
    // + " mirror type is not KEYS_VALUES ");

    if (logger.fineEnabled()) {
      logger.fine("testpartionedRegionInitialization() Successfully Complete ..  ");
    }
    // System.out.println("testpartionedRegionInitialization");
  }

  /**
   * Test for partitioned Region registration. All partitioned regions created must have a entry in
   * PARTITIONED_REGION_CONFIG_NAME. Every PR has PR name / PartitionRegionConfig entry in region
   * PARTITIONED_REGION_CONFIG_NAME
   *
   */
  @Test
  public void test003partionedRegionRegistration() {
    createMultiplePartitionedRegions();
    Region root = (PartitionedRegionTestHelper
        .getExistingRegion(PartitionedRegionHelper.PR_ROOT_REGION_NAME));
    //
    // Region allPartitionedRegions = root
    // .getSubregion(PartitionedRegionHelper.PARTITIONED_REGION_CONFIG_NAME);

    Iterator itr = PRRegionList.iterator();
    while (itr.hasNext()) {
      Region region = (Region) itr.next();
      String name = ((PartitionedRegion) region).getRegionIdentifier();
      PartitionRegionConfig prConfig = (PartitionRegionConfig) root.get(name);
      if (prConfig == null)
        fail("testpartionedRegionRegistration() - PartionedRegion - " + name
            + " configs do not exists in  region - " + root.getName());
    }

    if (logger.fineEnabled()) {
      logger.fine(" testpartionedRegionRegistration() Successfully Complete ..  ");
    }
    // System.out.println("testpartionedRegionRegistration");
  }

  /**
   * creates multiple partitioned region from different threads.
   *
   */
  private void createMultiplePartitionedRegions() {
    if (PRCreateDone)
      return;
    int numthread = 0;
    while (numthread < TOTAL_THREADS) {
      PartionedRegionCreateThread pregionThread = new PartionedRegionCreateThread();
      pregionThread.start();
      numthread++;
    }
    while (!createComplete) {
      synchronized (CREATE_COMPLETE_LOCK) {
        if (!createComplete) {
          try {
            CREATE_COMPLETE_LOCK.wait();
          } catch (Exception ex) { // no action }
          }
        }
      }
    }
    PRCreateDone = true;
  }

  /**
   * Verifies creation of partitioned region.
   *
   */
  private void verifyCreateResults() {
    if (TOTAL_RETURNS != TOTAL_THREADS)
      fail("Failed -- Total thread returned is not same as number of threads created");

    if (TOTAL_PR_CREATED != (TOTAL_THREADS / 2))
      fail("Failed -- Total Partioned Region created is not correct");

    if (TOTAL_PR_CREATION_FAIL != (TOTAL_THREADS / 2))
      fail("Failed -- Total Partioned Region creation failures is not correct");
  }

  /**
   * Thread to create the partitioned region.
   *
   */
  public class PartionedRegionCreateThread extends Thread {
    @Override
    public void run() {
      String prName = "PartitionedRegionCreationJUnitTest_" + getPRNumber();
      try {
        Region region = PartitionedRegionTestHelper.createPartionedRegion(prName);
        PRRegionList.add(region);
        if (logger.fineEnabled()) {
          logger.fine(
              "PartitionedRegionCreationJUnitTest - partitioned region -" + prName + "Created");
        }
        updatePRCreate();
      } catch (RegionExistsException rex) {
        if (logger.fineEnabled()) {
          logger
              .fine("PartitionedRegionCreationTest -  Thread - " + Thread.currentThread().getName()
                  + " Failed to create a PartitionedRegion. Region already exists");
        }
        updatePRCreateFail();
      }

      updateTotalReturns();
    }
  }

  /**
   * Increments and returns the PR nmber used for PR creation. Thread safe function.
   *
   * @return the PR number
   */
  protected int getPRNumber() {
    int retNum = 0;
    synchronized (PR_INCREMENT) {
      if (increamentFlag) {
        retNum = PRNumber;
        PRNumber++;
        increamentFlag = false;
      } else {
        increamentFlag = true;
      }
    }
    return retNum;
  }

  protected void updatePRCreate() {
    synchronized (PR_CREATE) {
      TOTAL_PR_CREATED++;
    }
  }

  protected void updatePRCreateFail() {
    synchronized (PR_CREATE_FAIL) {
      TOTAL_PR_CREATION_FAIL++;
    }
  }

  /**
   * Increments total creation thread returns.
   *
   */
  protected void updateTotalReturns() {
    synchronized (PR_TOTAL_RETURNS) {
      TOTAL_RETURNS++;
      System.out.println("TOTAL_RETURNS is " + TOTAL_RETURNS);
    }
    if (TOTAL_RETURNS == TOTAL_THREADS) {
      synchronized (CREATE_COMPLETE_LOCK) {
        createComplete = true;
        CREATE_COMPLETE_LOCK.notifyAll();
      }
    }
  }
}
