/*
 * 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.test.dunit.cache.internal;

import static org.apache.geode.distributed.ConfigurationProperties.MCAST_PORT;
import static org.apache.geode.distributed.internal.DistributionConfig.GEMFIRE_PREFIX;
import static org.apache.geode.test.awaitility.GeodeAwaitility.await;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Map;
import java.util.Properties;

import org.apache.logging.log4j.Logger;

import org.apache.geode.cache.AttributesFactory;
import org.apache.geode.cache.Cache;
import org.apache.geode.cache.CacheException;
import org.apache.geode.cache.CacheFactory;
import org.apache.geode.cache.CacheTransactionManager;
import org.apache.geode.cache.DataPolicy;
import org.apache.geode.cache.ExpirationAttributes;
import org.apache.geode.cache.Region;
import org.apache.geode.cache.RegionAttributes;
import org.apache.geode.cache.RegionExistsException;
import org.apache.geode.cache.TimeoutException;
import org.apache.geode.cache.client.ClientCache;
import org.apache.geode.cache.client.ClientCacheFactory;
import org.apache.geode.cache.client.PoolManager;
import org.apache.geode.cache30.CacheSerializableRunnable;
import org.apache.geode.distributed.internal.DistributionMessageObserver;
import org.apache.geode.internal.cache.GemFireCacheImpl;
import org.apache.geode.internal.cache.InternalCache;
import org.apache.geode.internal.cache.LocalRegion;
import org.apache.geode.internal.cache.xmlcache.CacheCreation;
import org.apache.geode.internal.cache.xmlcache.CacheXmlGenerator;
import org.apache.geode.internal.logging.LogService;
import org.apache.geode.test.dunit.IgnoredException;
import org.apache.geode.test.dunit.Invoke;
import org.apache.geode.test.dunit.VM;
import org.apache.geode.test.dunit.internal.JUnit4DistributedTestCase;
import org.apache.geode.test.dunit.rules.ClusterStartupRule;
import org.apache.geode.test.dunit.rules.DistributedRule;

/**
 * This class is the base class for all distributed tests using JUnit 4 that require the creation of
 * a {@link Cache}.
 *
 * @deprecated Please use {@link DistributedRule} and Geode User APIs or {@link ClusterStartupRule}
 *             instead.
 */
public abstract class JUnit4CacheTestCase extends JUnit4DistributedTestCase
    implements CacheTestFixture {

  private static final Logger logger = LogService.getLogger();
  /**
   * The Cache from which regions are obtained.
   *
   * <p>
   * All references synchronized via {@code JUnit4CacheTestCase.class}.
   *
   * <p>
   * Field is static so it doesn't get serialized with SerializableRunnable inner classes.
   */
  protected static InternalCache cache;

  private final CacheTestFixture cacheTestFixture;

  public JUnit4CacheTestCase() {
    this(null);
  }

  JUnit4CacheTestCase(final CacheTestFixture cacheTestFixture) {
    super(cacheTestFixture);
    if (cacheTestFixture == null) {
      this.cacheTestFixture = this;
    } else {
      this.cacheTestFixture = cacheTestFixture;
    }
  }

  /**
   * Creates the {@code Cache} for this test
   */
  private final void createCache() {
    createCache(false);
  }

  private final void createCache(final boolean client) {
    createCache(client, null);
  }

  private final void createCache(final boolean client, final CacheFactory factory) {
    synchronized (JUnit4CacheTestCase.class) {
      try {
        System.setProperty(GEMFIRE_PREFIX + "DISABLE_DISCONNECT_DS_ON_CACHE_CLOSE", "true");
        InternalCache newCache;
        if (client) {
          System.setProperty(GEMFIRE_PREFIX + "locators", "");
          System.setProperty(GEMFIRE_PREFIX + MCAST_PORT, "0");
          newCache = (InternalCache) new ClientCacheFactory(getSystem().getProperties()).create();
        } else {
          if (factory == null) {
            newCache = (InternalCache) CacheFactory.create(getSystem());
          } else {
            Properties config = getSystem().getProperties();
            for (Map.Entry entry : config.entrySet()) {
              factory.set((String) entry.getKey(), (String) entry.getValue());
            }
            newCache = (InternalCache) factory.create();
          }
        }
        cache = newCache;
      } finally {
        System.clearProperty(GEMFIRE_PREFIX + "DISABLE_DISCONNECT_DS_ON_CACHE_CLOSE");
        System.clearProperty(GEMFIRE_PREFIX + "locators");
        System.clearProperty(GEMFIRE_PREFIX + MCAST_PORT);
      }
    }
  }

  /**
   * Creates the {@code Cache} for this test that is not connected to other members.
   */
  public final InternalCache createLonerCache() {
    synchronized (JUnit4CacheTestCase.class) {
      try {
        System.setProperty(GEMFIRE_PREFIX + "DISABLE_DISCONNECT_DS_ON_CACHE_CLOSE", "true");
        InternalCache newCache = (InternalCache) CacheFactory.create(getLonerSystem());
        cache = newCache;
      } finally {
        System.clearProperty(GEMFIRE_PREFIX + "DISABLE_DISCONNECT_DS_ON_CACHE_CLOSE");
      }
      return cache;
    }
  }

  /**
   * Sets this test up with a {@code CacheCreation} as its cache. Any existing cache is closed.
   * Whoever calls this must also call {@code finishCacheXml}.
   */
  public static synchronized void beginCacheXml() {
    closeCache();
    cache = new TestCacheCreation();
  }

  /**
   * Finish what {@code beginCacheXml} started. It does this be generating a cache.xml file and then
   * creating a real cache using that cache.xml.
   */
  public final void finishCacheXml(final String name) {
    synchronized (JUnit4CacheTestCase.class) {
      try {
        File file = new File(name + "-cache.xml");
        PrintWriter printWriter = new PrintWriter(new FileWriter(file), true);
        CacheXmlGenerator.generate(cache, printWriter);
        printWriter.close();
        cache = null;
        GemFireCacheImpl.testCacheXml = file;
        createCache();
      } catch (Exception ex) {
        throw new RuntimeException(ex);
      } finally {
        GemFireCacheImpl.testCacheXml = null;
      }
    }
  }

  /**
   * Finish what {@code beginCacheXml} started. It does this be generating a cache.xml file and then
   * creating a real cache using that cache.xml.
   */
  public final void finishCacheXml(final File root, final String name, final boolean useSchema,
      final String xmlVersion) throws IOException {
    synchronized (JUnit4CacheTestCase.class) {
      File dir = new File(root, "XML_" + xmlVersion);
      dir.mkdirs();
      File file = new File(dir, name + ".xml");
      PrintWriter printWriter = new PrintWriter(new FileWriter(file), true);
      CacheXmlGenerator.generate(cache, printWriter, useSchema, xmlVersion);
      printWriter.close();
      cache = null;
      GemFireCacheImpl.testCacheXml = file;
      try {
        createCache();
      } finally {
        GemFireCacheImpl.testCacheXml = null;
      }
    }
  }

  /**
   * Return a cache for obtaining regions, created lazily.
   */
  public final InternalCache getCache() {
    return getCache(false);
  }

  public final InternalCache getCache(final CacheFactory factory) {
    return getCache(false, factory);
  }

  public final InternalCache getCache(final Properties properties) {
    getSystem(properties);
    return getCache();
  }

  public final InternalCache getCache(final boolean client) {
    return getCache(client, null);
  }

  public final InternalCache getCache(final boolean client, final CacheFactory factory) {
    synchronized (JUnit4CacheTestCase.class) {
      InternalCache gemFireCache = GemFireCacheImpl.getInstance();
      if (gemFireCache != null && !gemFireCache.isClosed()
          && gemFireCache.getCancelCriterion().isCancelInProgress()) {
        await("waiting for cache to close")
            .until(gemFireCache::isClosed);
      }
      if (cache == null || cache.isClosed()) {
        cache = null;
        createCache(client, factory);
      }
      if (client && cache != null) {
        IgnoredException.addIgnoredException("java.net.ConnectException");
      }
      return cache;
    }
  }

  /**
   * Creates a client cache from the factory if one does not already exist.
   *
   * @since GemFire 6.5
   */
  public final ClientCache getClientCache(final ClientCacheFactory factory) {
    synchronized (JUnit4CacheTestCase.class) {
      InternalCache gemFireCache = GemFireCacheImpl.getInstance();
      if (gemFireCache != null && !gemFireCache.isClosed()
          && gemFireCache.getCancelCriterion().isCancelInProgress()) {
        await("waiting for cache to close")
            .until(gemFireCache::isClosed);
      }
      if (cache == null || cache.isClosed()) {
        cache = null;
        disconnectFromDS();
        cache = (InternalCache) factory.create();
      }
      if (cache != null) {
        IgnoredException.addIgnoredException("java.net.ConnectException");
      }
      return (ClientCache) cache;
    }
  }

  public final ClientCache getClientCache() {
    return (ClientCache) cache;
  }

  /**
   * Invokes {@link #getCache()} and casts the return to {@code GemFireCacheImpl}.
   *
   * <p>
   * TODO: change all callers to use getCache and delete getGemfireCache
   *
   * @deprecated Please use {@link #getCache} which returns InternalCache instead.
   */
  @Deprecated
  public final GemFireCacheImpl getGemfireCache() {
    return (GemFireCacheImpl) getCache();
  }

  public static final synchronized boolean hasCache() {
    return cache != null;
  }

  /**
   * Return current cache without creating one.
   */
  public static final synchronized InternalCache basicGetCache() {
    return cache;
  }

  /**
   * Close the cache.
   */
  public static final synchronized void closeCache() {
    // Workaround for the fact that some classes are now extending
    // CacheTestCase but not using it properly.
    if (cache == null) {
      cache = GemFireCacheImpl.getInstance();
    }
    try {
      if (cache != null) {
        try {
          if (!cache.isClosed()) {
            if (cache instanceof GemFireCacheImpl) {
              // this unnecessary type-cast prevents NoSuchMethodError
              // java.lang.NoSuchMethodError:
              // org.apache.geode.internal.cache.InternalCache.getTxManager()Lorg/apache/geode/internal/cache/TXManagerImpl
              CacheTransactionManager transactionManager =
                  ((GemFireCacheImpl) cache).getTxManager();
              if (transactionManager != null) {
                if (transactionManager.exists()) {
                  try {
                    // make sure we cleanup this threads txid stored in a thread local
                    transactionManager.rollback();
                  } catch (Exception ignore) {

                  }
                }
              }
            }
            cache.close();
          }
        } finally {
          cache = null;
        }
      } // cache != null
    } finally {
      // Make sure all pools are closed, even if we never created a cache
      PoolManager.close(false);
    }
  }

  /**
   * Close the cache in all VMs.
   */
  protected final void closeAllCache() {
    closeCache();
    Invoke.invokeInEveryVM(JUnit4CacheTestCase::closeCache);
  }

  @Override
  public final void preTearDown() throws Exception {
    preTearDownCacheTestCase();
    tearDownCacheTestCase();
    postTearDownCacheTestCase();
  }

  private final void tearDownCacheTestCase() {
    remoteTearDown();
    Invoke.invokeInEveryVM(JUnit4CacheTestCase::remoteTearDown);
  }

  @Override
  public void preTearDownCacheTestCase() throws Exception {
    if (this.cacheTestFixture != this) {
      this.cacheTestFixture.preTearDownCacheTestCase();
    }
  }

  @Override
  public void postTearDownCacheTestCase() throws Exception {
    if (this.cacheTestFixture != this) {
      this.cacheTestFixture.postTearDownCacheTestCase();
    }
  }

  /**
   * Local destroy all root regions and close the cache.
   */
  private static synchronized void remoteTearDown() {
    try {
      DistributionMessageObserver.setInstance(null);
      destroyRegions(cache);
    } finally {
      try {
        closeCache();
      } finally {
        try {
          cleanDiskDirs();
        } catch (Exception e) {
          logger.error("Error cleaning disk dirs", e);
        }
      }
    }
  }

  /**
   * Returns a region with the given name and attributes.
   */
  public final <K, V> Region<K, V> createRegion(final String name,
      final RegionAttributes<K, V> attributes)
      throws CacheException {
    return createRegion(name, "root", attributes);
  }

  public final <K, V> Region<K, V> createPartitionedRegion(final String rootName,
      final RegionAttributes<K, V> attributes) throws CacheException {
    Region<K, V> root = getRootRegion(rootName);
    if (root == null) {
      // don't put listeners on root region
      AttributesFactory<K, V> attributesFactory = new AttributesFactory<>(attributes);
      ExpirationAttributes expiration = ExpirationAttributes.DEFAULT;

      attributesFactory.setCacheLoader(null);
      attributesFactory.setCacheWriter(null);
      attributesFactory.setPoolName(null);
      attributesFactory.setDataPolicy(DataPolicy.PARTITION);
      attributesFactory.setRegionTimeToLive(expiration);
      attributesFactory.setEntryTimeToLive(expiration);
      attributesFactory.setRegionIdleTimeout(expiration);
      attributesFactory.setEntryIdleTimeout(expiration);

      RegionAttributes<K, V> rootAttrs = attributesFactory.create();
      root = createRootRegion(rootName, rootAttrs);
    }
    return root;
  }

  public final <K, V> Region<K, V> createRegion(final String name, final String rootName,
      final RegionAttributes<K, V> attributes) throws CacheException {
    Region<K, V> root = getRootRegion(rootName);
    if (root == null) {
      // don't put listeners on root region
      AttributesFactory<K, V> attributesFactory = new AttributesFactory<>(attributes);
      ExpirationAttributes expiration = ExpirationAttributes.DEFAULT;

      attributesFactory.setCacheLoader(null);
      attributesFactory.setCacheWriter(null);
      attributesFactory.setPoolName(null);
      attributesFactory.setPartitionAttributes(null);
      attributesFactory.setRegionTimeToLive(expiration);
      attributesFactory.setEntryTimeToLive(expiration);
      attributesFactory.setRegionIdleTimeout(expiration);
      attributesFactory.setEntryIdleTimeout(expiration);

      RegionAttributes<K, V> rootAttrs = attributesFactory.create();
      root = createRootRegion(rootName, rootAttrs);
    }

    return root.createSubregion(name, attributes);
  }

  public final <K, V> Region<K, V> getRootRegion() {
    return getRootRegion("root");
  }

  public final <K, V> Region<K, V> getRootRegion(final String rootName) {
    return getCache().getRegion(rootName);
  }

  protected final <K, V> Region<K, V> createRootRegion(final RegionAttributes<K, V> attributes)
      throws RegionExistsException, TimeoutException {
    return createRootRegion("root", attributes);
  }

  public final <K, V> Region<K, V> createRootRegion(final String rootName,
      final RegionAttributes<K, V> attributes)
      throws RegionExistsException, TimeoutException {
    return getCache().createRegion(rootName, attributes);
  }

  public final <K, V> Region<K, V> createExpiryRootRegion(final String rootName,
      final RegionAttributes<K, V> attributes) throws RegionExistsException, TimeoutException {
    System.setProperty(LocalRegion.EXPIRY_MS_PROPERTY, "true");
    try {
      return createRootRegion(rootName, attributes);
    } finally {
      System.clearProperty(LocalRegion.EXPIRY_MS_PROPERTY);
    }
  }

  /**
   * @deprecated Please use {@link IgnoredException#addIgnoredException(String)} instead.
   */
  @Deprecated
  public final CacheSerializableRunnable addExceptionTag1(final String exceptionStringToIgnore) {
    return new CacheSerializableRunnable("addExceptionTag") {
      @Override
      public void run2() {
        getCache().getLogger().info(
            "<ExpectedException action=add>" + exceptionStringToIgnore + "</ExpectedException>");
      }
    };
  }

  /**
   * TODO: delete removeExceptionTag1 method
   *
   * @deprecated Please use {@link IgnoredException#addIgnoredException(String)} instead.
   */
  @Deprecated
  public final CacheSerializableRunnable removeExceptionTag1(final String exceptionStringToIgnore) {
    return new CacheSerializableRunnable("removeExceptionTag") {

      @Override
      public void run2() throws CacheException {
        getCache().getLogger().info(
            "<ExpectedException action=remove>" + exceptionStringToIgnore + "</ExpectedException>");
      }
    };
  }

  public static final File getDiskDir() {
    int vmNum = VM.getCurrentVMNum();
    File dir = new File("diskDir", "disk" + String.valueOf(vmNum)).getAbsoluteFile();
    dir.mkdirs();
    return dir;
  }

  /**
   * Return a set of disk directories for persistence tests. These directories will be automatically
   * cleaned up on test case closure.
   */
  public static final File[] getDiskDirs() {
    return new File[] {getDiskDir()};
  }

  /**
   * Used to generate a cache.xml. Basically just a {@code CacheCreation} with a few more methods
   * implemented.
   */
  private static class TestCacheCreation extends CacheCreation {
    private boolean closed = false;

    @Override
    public void close() {
      this.closed = true;
    }

    @Override
    public boolean isClosed() {
      return this.closed;
    }
  }
}
