package org.infinispan.api.flags;

import static org.infinispan.context.Flag.CACHE_MODE_LOCAL;

import java.lang.reflect.Method;

import org.infinispan.AdvancedCache;
import org.infinispan.configuration.cache.CacheMode;
import org.infinispan.configuration.cache.ConfigurationBuilder;
import org.infinispan.distribution.MagicKey;
import org.infinispan.manager.EmbeddedCacheManager;
import org.infinispan.persistence.UnnecessaryLoadingTest;
import org.infinispan.persistence.dummy.DummyInMemoryStoreConfigurationBuilder;
import org.infinispan.test.TestDataSCI;
import org.infinispan.test.fwk.CleanupAfterMethod;
import org.testng.annotations.Test;

/**
 * FlagsEnabledTest for non transactional caches.
 *
 * @author Pedro Ruivo
 * @since 6.0
 */
@Test(groups = "functional", testName = "api.flags.NonTxFlagsEnabledTest")
@CleanupAfterMethod
public class NonTxFlagsEnabledTest extends FlagsEnabledTest {

   public NonTxFlagsEnabledTest() {
      super("non-tx-replication");
   }

   @Override
   @Test(enabled = false, description = "non transactional cache")
   public void testReplicateSkipCacheLoaderWithinTxInCoordinator(Method m) throws Exception {
   }

   @Override
   @Test(enabled = false, description = "non transactional cache")
   public void testReplicateSkipCacheLoaderWithinTxInNonCoordinator(Method m) throws Exception {
   }

   public void testCacheLocalInNonOwner() {
      EmbeddedCacheManager cm = addClusterEnabledCacheManager(TestDataSCI.INSTANCE);
      cm.createCache(cacheName, getConfigurationBuilder().build());
      waitForClusterToForm(cacheName);
      final AdvancedCache<Object, String> cache1 = advancedCache(0, cacheName);
      final AdvancedCache<Object, String> cache2 = advancedCache(1, cacheName);
      final AdvancedCache<Object, String> cache3 = advancedCache(2, cacheName);
      final Object key = new MagicKey("k-no", cache1);

      cache3.withFlags(CACHE_MODE_LOCAL).put(key, "value");

      assertCacheValue(cache3, key, "value");
      assertCacheValue(cache1, key, null);
      assertCacheValue(cache2, key, null);
   }

   @Override
   protected void createCacheManagers() throws Throwable {
      ConfigurationBuilder builder = getDefaultClusteredCacheConfig(CacheMode.REPL_SYNC, false);
      builder.persistence().addStore(DummyInMemoryStoreConfigurationBuilder.class);
      createClusteredCaches(2, cacheName, TestDataSCI.INSTANCE, builder);
   }

   private ConfigurationBuilder getConfigurationBuilder() {
      ConfigurationBuilder builder = getDefaultClusteredCacheConfig(CacheMode.REPL_SYNC, false);
      builder
            .persistence().addStore(UnnecessaryLoadingTest.CountingStoreConfigurationBuilder.class)
            .persistence().addStore(DummyInMemoryStoreConfigurationBuilder.class);
      return builder;
   }
}
