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

import static org.junit.Assert.assertNotNull;

import java.util.HashSet;
import java.util.Properties;
import java.util.Set;

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

import org.apache.geode.cache.AttributesFactory;
import org.apache.geode.cache.Cache;
import org.apache.geode.cache.CacheFactory;
import org.apache.geode.cache.DataPolicy;
import org.apache.geode.cache.PartitionAttributesFactory;
import org.apache.geode.cache.Region;
import org.apache.geode.cache.Scope;
import org.apache.geode.cache.execute.FunctionAdapter;
import org.apache.geode.cache.execute.FunctionContext;
import org.apache.geode.distributed.ConfigurationProperties;
import org.apache.geode.distributed.DistributedSystem;
import org.apache.geode.internal.Assert;
import org.apache.geode.test.dunit.Host;
import org.apache.geode.test.dunit.Invoke;
import org.apache.geode.test.dunit.SerializableRunnable;
import org.apache.geode.test.dunit.VM;
import org.apache.geode.test.dunit.cache.internal.JUnit4CacheTestCase;
import org.apache.geode.test.junit.categories.FunctionServiceTest;

@SuppressWarnings("serial")
@Category({FunctionServiceTest.class})
public class MultiRegionFunctionExecutionDUnitTest extends JUnit4CacheTestCase {

  VM vm0 = null;

  VM vm1 = null;

  VM vm2 = null;

  VM vm3 = null;

  static Region PR1 = null;
  static Region PR2 = null;
  static Region RR1 = null;
  static Region RR2 = null;
  static Region LR1 = null;
  static Cache cache = null;

  public MultiRegionFunctionExecutionDUnitTest() {
    super();
  }

  @Override
  public final void postSetUp() throws Exception {
    Host host = Host.getHost(0);
    vm0 = host.getVM(0);
    vm1 = host.getVM(1);
    vm2 = host.getVM(2);
    vm3 = host.getVM(3);
  }

  @Override
  public final void postTearDownCacheTestCase() throws Exception {
    cache = null;
    Invoke.invokeInEveryVM(new SerializableRunnable() {
      @Override
      public void run() {
        cache = null;
      }
    });
  }

  @Test
  public void testMultiRegionFunctionExecution() {
    vm0.invoke(() -> MultiRegionFunctionExecutionDUnitTest.createRegionsOnVm0());
    vm1.invoke(() -> MultiRegionFunctionExecutionDUnitTest.createRegionsOnVm1());
    vm2.invoke(() -> MultiRegionFunctionExecutionDUnitTest.createRegionsOnVm2());
    vm3.invoke(() -> MultiRegionFunctionExecutionDUnitTest.createRegionsOnVm3());
    createRegionsOnUnitControllerVm();
    Set<Region> regions = new HashSet<Region>();
    regions.add(PR1);
    InternalFunctionService.onRegions(regions).execute(new FunctionAdapter() {

      @Override
      public void execute(FunctionContext context) {
        MultiRegionFunctionContext mrContext = (MultiRegionFunctionContext) context;
        Set<Region> regions = mrContext.getRegions();
        Assert.assertTrue(1 == regions.size());
        context.getResultSender().lastResult(Boolean.TRUE);
      }

      @Override
      public String getId() {
        // TODO Auto-generated method stub
        return getClass().getName();
      }

    }).getResult();
    regions.add(PR2);
    InternalFunctionService.onRegions(regions).execute(new FunctionAdapter() {

      @Override
      public void execute(FunctionContext context) {
        MultiRegionFunctionContext mrContext = (MultiRegionFunctionContext) context;
        Set<Region> regions = mrContext.getRegions();
        Assert.assertTrue(0 != regions.size());
        context.getResultSender().lastResult(Boolean.TRUE);
      }

      @Override
      public String getId() {
        // TODO Auto-generated method stub
        return getClass().getName();
      }

    }).getResult();

    regions.add(PR2);
    regions.add(RR1);
    regions.add(RR2);
    regions.add(LR1);
    InternalFunctionService.onRegions(regions).execute(new FunctionAdapter() {

      @Override
      public void execute(FunctionContext context) {
        MultiRegionFunctionContext mrContext = (MultiRegionFunctionContext) context;
        Set<Region> regions = mrContext.getRegions();
        Assert.assertTrue(0 != regions.size());
        context.getResultSender().lastResult(Boolean.TRUE);
      }

      @Override
      public String getId() {
        // TODO Auto-generated method stub
        return getClass().getName();
      }

    }).getResult();
  }

  @Override
  public Properties getDistributedSystemProperties() {
    Properties props = super.getDistributedSystemProperties();
    props.put(ConfigurationProperties.SERIALIZABLE_OBJECT_FILTER,
        "org.apache.geode.internal.cache.execute.MultiRegionFunctionExecutionDUnitTest*"
            + ";org.apache.geode.test.dunit.**" + ";org.apache.geode.test.junit.rules.**"
            + ";com.sun.proxy.**");
    return props;
  }

  public void createCache() {
    try {
      Properties props = getDistributedSystemProperties();
      DistributedSystem ds = getSystem(props);
      assertNotNull(ds);
      ds.disconnect();
      ds = getSystem(props);
      cache = CacheFactory.create(ds);
      assertNotNull(cache);
    } catch (Exception e) {
      org.apache.geode.test.dunit.Assert.fail("Failed while creating the cache", e);
    }
  }

  @SuppressWarnings("unchecked")
  public static void createRegionsOnVm0() {
    new MultiRegionFunctionExecutionDUnitTest().createCache();

    PartitionAttributesFactory pf = new PartitionAttributesFactory();
    pf.setTotalNumBuckets(12);
    pf.setRedundantCopies(1);
    AttributesFactory factory = new AttributesFactory();
    factory.setPartitionAttributes(pf.create());
    cache.createRegion("PR1", factory.create());

    factory = new AttributesFactory();
    factory.setDataPolicy(DataPolicy.REPLICATE);
    cache.createRegion("RR1", factory.create());

    factory = new AttributesFactory();
    factory.setDataPolicy(DataPolicy.EMPTY);
    cache.createRegion("RR2", factory.create());
  }

  @SuppressWarnings("unchecked")
  public static void createRegionsOnVm1() {
    new MultiRegionFunctionExecutionDUnitTest().createCache();

    PartitionAttributesFactory pf = new PartitionAttributesFactory();
    pf.setTotalNumBuckets(12);
    pf.setRedundantCopies(1);
    AttributesFactory factory = new AttributesFactory();
    factory.setPartitionAttributes(pf.create());
    cache.createRegion("PR1", factory.create());

    factory = new AttributesFactory();
    factory.setDataPolicy(DataPolicy.NORMAL);
    cache.createRegion("RR1", factory.create());

    factory = new AttributesFactory();
    factory.setDataPolicy(DataPolicy.REPLICATE);
    cache.createRegion("RR2", factory.create());
  }

  @SuppressWarnings("unchecked")
  public static void createRegionsOnVm2() {
    new MultiRegionFunctionExecutionDUnitTest().createCache();

    PartitionAttributesFactory pf = new PartitionAttributesFactory();
    pf.setTotalNumBuckets(12);
    pf.setRedundantCopies(1);
    pf.setLocalMaxMemory(0);
    AttributesFactory factory = new AttributesFactory();
    factory.setPartitionAttributes(pf.create());
    cache.createRegion("PR1", factory.create());


    pf = new PartitionAttributesFactory();
    pf.setTotalNumBuckets(12);
    pf.setRedundantCopies(1);
    factory = new AttributesFactory();
    factory.setPartitionAttributes(pf.create());
    cache.createRegion("PR2", factory.create());

    factory = new AttributesFactory();
    factory.setDataPolicy(DataPolicy.EMPTY);
    cache.createRegion("RR1", factory.create());

    factory = new AttributesFactory();
    factory.setDataPolicy(DataPolicy.NORMAL);
    cache.createRegion("RR2", factory.create());
  }

  @SuppressWarnings("unchecked")
  public static void createRegionsOnVm3() {
    new MultiRegionFunctionExecutionDUnitTest().createCache();

    PartitionAttributesFactory pf = new PartitionAttributesFactory();
    pf.setTotalNumBuckets(12);
    pf.setRedundantCopies(1);
    AttributesFactory factory = new AttributesFactory();
    factory.setPartitionAttributes(pf.create());
    cache.createRegion("PR1", factory.create());


    pf = new PartitionAttributesFactory();
    pf.setTotalNumBuckets(12);
    pf.setRedundantCopies(1);
    factory = new AttributesFactory();
    factory.setPartitionAttributes(pf.create());
    cache.createRegion("PR2", factory.create());

    factory = new AttributesFactory();
    factory.setDataPolicy(DataPolicy.REPLICATE);
    cache.createRegion("RR1", factory.create());

    factory = new AttributesFactory();
    factory.setDataPolicy(DataPolicy.REPLICATE);
    cache.createRegion("RR2", factory.create());
  }

  @SuppressWarnings("unchecked")
  public static void createRegionsOnUnitControllerVm() {
    new MultiRegionFunctionExecutionDUnitTest().createCache();

    PartitionAttributesFactory pf = new PartitionAttributesFactory();
    pf.setTotalNumBuckets(12);
    pf.setRedundantCopies(1);
    AttributesFactory factory = new AttributesFactory();
    factory.setPartitionAttributes(pf.create());
    PR1 = cache.createRegion("PR1", factory.create());


    pf = new PartitionAttributesFactory();
    pf.setTotalNumBuckets(12);
    pf.setRedundantCopies(1);
    pf.setLocalMaxMemory(0);
    factory = new AttributesFactory();
    factory.setPartitionAttributes(pf.create());
    PR2 = cache.createRegion("PR2", factory.create());

    factory = new AttributesFactory();
    factory.setDataPolicy(DataPolicy.REPLICATE);
    RR1 = cache.createRegion("RR1", factory.create());

    factory = new AttributesFactory();
    factory.setDataPolicy(DataPolicy.EMPTY);
    RR2 = cache.createRegion("RR2", factory.create());

    factory = new AttributesFactory();
    factory.setScope(Scope.LOCAL);
    LR1 = cache.createRegion("LR1", factory.create());

    for (int i = 0; i < 24; i++) {
      PR1.put(new Integer(i), new Integer(i));
      PR2.put(new Integer(i), new Integer(i));
      RR1.put(new Integer(i), new Integer(i));
      RR2.put(new Integer(i), new Integer(i));
      LR1.put(new Integer(i), new Integer(i));
    }
  }

}
