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

import org.junit.Test;

import org.apache.geode.cache.AttributesFactory;
import org.apache.geode.cache.CacheWriter;
import org.apache.geode.cache.CacheWriterException;
import org.apache.geode.cache.EntryEvent;
import org.apache.geode.cache.PartitionAttributesFactory;
import org.apache.geode.cache.Region;
import org.apache.geode.cache.RegionEvent;
import org.apache.geode.cache.util.CacheListenerAdapter;
import org.apache.geode.cache.util.CacheWriterAdapter;
import org.apache.geode.test.dunit.Host;
import org.apache.geode.test.dunit.SerializableCallable;
import org.apache.geode.test.dunit.VM;
import org.apache.geode.test.dunit.cache.internal.JUnit4CacheTestCase;

/**
 * This tests invalidateRegion functionality on partitioned regions
 *
 */

public class PartitionedRegionInvalidateDUnitTest extends JUnit4CacheTestCase {

  public PartitionedRegionInvalidateDUnitTest() {
    super();
  }

  void createRegion(String name, boolean accessor, int redundantCopies, CacheWriter w) {
    AttributesFactory af = new AttributesFactory();
    af.setCacheWriter(w);
    af.setPartitionAttributes(new PartitionAttributesFactory().setLocalMaxMemory(accessor ? 0 : 12)
        .setRedundantCopies(redundantCopies).create());
    getCache().createRegion(name, af.create());
  }

  @Test
  public void testSingleVMInvalidate() {
    Host host = Host.getHost(0);
    VM vm = host.getVM(0);
    final String rName = getUniqueName();
    vm.invoke(new SerializableCallable() {
      @Override
      public Object call() throws Exception {
        createRegion(rName, false, 0, null);
        Region r = getCache().getRegion(rName);
        InvalidatePRListener l = new InvalidatePRListener();
        r.getAttributesMutator().addCacheListener(l);
        for (int i = 0; i <= 113; i++) {
          r.put(i, "value" + i);
        }
        PartitionedRegion pr = (PartitionedRegion) r;
        assertTrue(pr.getDataStore().getAllLocalBuckets().size() == 113);
        for (Object v : pr.values()) {
          assertNotNull(v);
        }
        r.invalidateRegion();
        assertTrue(l.afterRegionInvalidateCalled);
        l.afterRegionInvalidateCalled = false;
        for (int i = 0; i <= 113; i++) {
          r.put(i, "value" + i);
        }
        Object callbackArg = "CallBACK";
        l.callbackArg = callbackArg;
        r.invalidateRegion(callbackArg);
        assertTrue(l.afterRegionInvalidateCalled);
        l.afterRegionInvalidateCalled = false;
        return null;
      }
    });
  }

  @Test
  public void testMultiVMInvalidate() {
    Host host = Host.getHost(0);
    VM vm0 = host.getVM(0);
    VM vm1 = host.getVM(1);
    VM vm2 = host.getVM(2);
    VM vm3 = host.getVM(3);
    final String rName = getUniqueName();

    class CreateRegion extends SerializableCallable {
      boolean originRemote;

      public CreateRegion(boolean originRemote) {
        this.originRemote = originRemote;
      }

      @Override
      public Object call() throws Exception {
        InvalidatePRWriter w = new InvalidatePRWriter();
        createRegion(rName, false, 1, w);
        Region r = getCache().getRegion(rName);
        InvalidatePRListener l = new InvalidatePRListener();
        l.originRemote = originRemote;
        r.getAttributesMutator().addCacheListener(l);
        return null;
      }
    };
    vm0.invoke(new CreateRegion(true));
    vm1.invoke(new CreateRegion(false));
    vm2.invoke(new CreateRegion(true));
    vm3.invoke(new CreateRegion(true));

    vm1.invoke(new SerializableCallable() {
      @Override
      public Object call() throws Exception {
        Region r = getCache().getRegion(rName);
        for (int i = 0; i <= 113; i++) {
          r.put(i, "value" + i);
        }
        for (int i = 0; i <= 113; i++) {
          assertNotNull(r.get(i));
        }
        r.invalidateRegion();

        return null;
      }
    });
    SerializableCallable validateCallbacks = new SerializableCallable() {
      @Override
      public Object call() throws Exception {
        Region r = getCache().getRegion(rName);
        InvalidatePRListener l = (InvalidatePRListener) r.getAttributes().getCacheListeners()[0];
        assertTrue(l.afterRegionInvalidateCalled);
        l.afterRegionInvalidateCalled = false;

        l.callbackArg = "CallBACK";
        return null;
      }
    };
    vm0.invoke(validateCallbacks);
    vm1.invoke(validateCallbacks);
    vm2.invoke(validateCallbacks);
    vm3.invoke(validateCallbacks);

    vm1.invoke(new SerializableCallable() {
      @Override
      public Object call() throws Exception {
        Region r = getCache().getRegion(rName);
        InvalidatePRListener l = (InvalidatePRListener) r.getAttributes().getCacheListeners()[0];
        for (int i = 0; i <= 113; i++) {
          r.put(i, "value" + i);
        }
        Object callbackArg = "CallBACK";
        l.callbackArg = callbackArg;
        r.invalidateRegion(callbackArg);

        return null;
      }
    });

    vm0.invoke(validateCallbacks);
    vm1.invoke(validateCallbacks);
    vm2.invoke(validateCallbacks);
    vm3.invoke(validateCallbacks);

    vm1.invoke(new SerializableCallable() {
      @Override
      public Object call() throws Exception {
        Region r = getCache().getRegion(rName);
        for (int i = 0; i <= 113; i++) {
          assertNull("Expected null but was " + r.get(i), r.get(i));
        }
        return null;
      }
    });
  }

  class InvalidatePRListener extends CacheListenerAdapter {
    Object callbackArg;
    boolean originRemote;
    boolean afterRegionInvalidateCalled;

    @Override
    public void afterInvalidate(EntryEvent event) {
      fail("After invalidate should not be called for individual entry");
    }

    @Override
    public void afterRegionInvalidate(RegionEvent event) {
      afterRegionInvalidateCalled = true;
      assertTrue(event.getOperation().isRegionInvalidate());
      assertEquals(originRemote, event.isOriginRemote());
      if (callbackArg != null) {
        assertTrue(event.isCallbackArgumentAvailable());
        assertEquals(callbackArg, event.getCallbackArgument());
      }
    }
  }

  class InvalidatePRWriter extends CacheWriterAdapter {
    @Override
    public void beforeRegionDestroy(RegionEvent event) throws CacheWriterException {
      fail("writer should not have been called");
    }

    @Override
    public void beforeRegionClear(RegionEvent event) throws CacheWriterException {
      fail("writer should not have been called");
    }

  }
}
