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

import static org.apache.geode.distributed.ConfigurationProperties.ENABLE_CLUSTER_CONFIGURATION;
import static org.apache.geode.distributed.ConfigurationProperties.MCAST_PORT;
import static org.apache.geode.distributed.ConfigurationProperties.USE_CLUSTER_CONFIGURATION;
import static org.junit.Assert.assertEquals;

import java.io.File;
import java.io.IOException;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;
import java.util.TreeMap;

import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;

import org.apache.geode.cache.Cache;
import org.apache.geode.cache.CacheFactory;
import org.apache.geode.cache.DataPolicy;
import org.apache.geode.cache.Region;
import org.apache.geode.cache.RegionFactory;
import org.apache.geode.cache.Scope;
import org.apache.geode.cache.client.ClientCache;
import org.apache.geode.cache.client.ClientCacheFactory;
import org.apache.geode.cache.client.ClientRegionShortcut;
import org.apache.geode.cache.snapshot.SnapshotIterator;
import org.apache.geode.cache.snapshot.SnapshotOptions.SnapshotFormat;
import org.apache.geode.cache.snapshot.SnapshotReader;
import org.apache.geode.distributed.LocatorLauncher;
import org.apache.geode.distributed.ServerLauncher;
import org.apache.geode.internal.AvailablePortHelper;
import org.apache.geode.test.dunit.DistributedTestUtils;
import org.apache.geode.test.dunit.Host;
import org.apache.geode.test.dunit.NetworkUtils;
import org.apache.geode.test.dunit.VM;
import org.apache.geode.test.dunit.internal.JUnit4DistributedTestCase;
import org.apache.geode.test.junit.rules.serializable.SerializableTemporaryFolder;


public class GFSnapshotDUnitTest extends JUnit4DistributedTestCase {

  private VM locator;
  private VM server;
  private VM client;
  private Host host;

  @Rule
  public SerializableTemporaryFolder temporaryFolder = new SerializableTemporaryFolder();

  @Before
  public void before() {
    host = Host.getHost(0);
    locator = host.getVM(0);
    server = host.getVM(1);
    client = host.getVM(2);
  }

  @Test
  public void testDataExportAndIterate() throws IOException, ClassNotFoundException {
    int locatorPort = AvailablePortHelper.getRandomAvailableTCPPort();
    String serverHostName = NetworkUtils.getServerHostName(host);

    Properties properties = configureCommonProperties(new Properties());

    locator.invoke("Start Locator",
        () -> configureAndStartLocator(locatorPort, serverHostName, properties));
    server.invoke("Start Server",
        () -> configureAndStartServer(locatorPort, serverHostName, properties));
    client.invoke("Start client", () -> {
      createAndStartClient(locatorPort, serverHostName);
      return null;
    });
    client.invoke("Populate data", () -> populateDataOnClient());
    String snapshotFilePath = server.invoke("Export data snapshot", () -> createSnapshot());
    client.invoke("Iterate over snapshot", () -> {
      ClientCache clientCache = ClientCacheFactory.getAnyInstance();
      clientCache.close();
      createAndStartClient(locatorPort, serverHostName);
      iterateOverSnapshot(snapshotFilePath);
    });
  }

  private void createAndStartClient(final int locatorPort, final String serverHostName) {
    ClientCacheFactory clientCacheFactory = new ClientCacheFactory();
    clientCacheFactory.set("log-level", "config").addPoolLocator(serverHostName, locatorPort);
    ClientCache clientCache = clientCacheFactory.create();
    clientCache.createClientRegionFactory(ClientRegionShortcut.PROXY).create("TestRegion");
  }

  private Object populateDataOnClient() {
    ClientCache clientCache = ClientCacheFactory.getAnyInstance();
    Region testRegion = clientCache.getRegion("TestRegion");
    for (int i = 0; i < 100; i++) {
      testRegion.put(i, new TestObject(i, "owner_" + i));
    }
    return null;
  }

  private String createSnapshot() throws IOException {
    final String memberName = getUniqueName() + "-server";
    File file = temporaryFolder.newFolder(memberName + "-snapshot");
    Cache cache = CacheFactory.getAnyInstance();
    cache.getSnapshotService().save(file, SnapshotFormat.GEMFIRE);
    return file.getAbsolutePath();
  }

  private void iterateOverSnapshot(final String snapshotFilePath)
      throws IOException, ClassNotFoundException {

    File mySnapshot = new File(snapshotFilePath + "/snapshot-TestRegion.gfd");
    SnapshotIterator<Integer, TestObject> snapshotIterator = SnapshotReader.read(mySnapshot);

    Map<Integer, TestObject> result = new TreeMap<>();

    try {
      while (snapshotIterator.hasNext()) {
        Entry<Integer, TestObject> entry = snapshotIterator.next();
        int key = entry.getKey();
        TestObject value = entry.getValue();
        result.put(key, value);
      }
    } finally {
      snapshotIterator.close();
    }
    assertEquals(100, result.size());
    int count = 0;
    for (Entry<Integer, TestObject> entry : result.entrySet()) {
      assertEquals(count, (int) entry.getKey());
      assertEquals(new TestObject(count, "owner_" + count), entry.getValue());
      count++;
    }
  }

  private Properties configureCommonProperties(final Properties properties) {
    properties.setProperty(MCAST_PORT, "0");
    properties.setProperty(ENABLE_CLUSTER_CONFIGURATION, "false");
    properties.setProperty(USE_CLUSTER_CONFIGURATION, "false");
    return properties;
  }

  private void configureAndStartLocator(final int locatorPort, final String serverHostName,
      final Properties properties) throws IOException {
    DistributedTestUtils.deleteLocatorStateFile(locatorPort);

    final String memberName = getUniqueName() + "-locator";
    final File workingDirectory = temporaryFolder.newFolder(memberName);

    LocatorLauncher.Builder builder = new LocatorLauncher.Builder();

    for (String propertyName : properties.stringPropertyNames()) {
      builder.set(propertyName, properties.getProperty(propertyName));
    }
    LocatorLauncher locatorLauncher = builder.setBindAddress(serverHostName)
        .setHostnameForClients(serverHostName).setMemberName(memberName).setPort(locatorPort)
        .setWorkingDirectory(workingDirectory.getCanonicalPath()).build();
    locatorLauncher.start();

  }

  private void configureAndStartServer(final int locatorPort, final String serverHostName,
      final Properties properties) throws IOException {
    final String memberName = getUniqueName() + "-server";
    final File workingDirectory = temporaryFolder.newFolder(memberName);
    final File pdxDirectory = temporaryFolder.newFolder(memberName + "-pdx");
    final File diskStoreDirectory = temporaryFolder.newFolder(memberName + "-disk");


    ServerLauncher.Builder builder = new ServerLauncher.Builder();

    for (String propertyName : properties.stringPropertyNames()) {
      builder.set(propertyName, properties.getProperty(propertyName));
    }

    ServerLauncher serverLauncher =
        builder.set("locators", serverHostName + "[" + locatorPort + "]").setMemberName(memberName)
            .set("log-level", "config").setHostNameForClients(serverHostName)
            .setServerBindAddress(serverHostName).setServerPort(0)
            .setWorkingDirectory(workingDirectory.getCanonicalPath()).setPdxDiskStore("pdxDS")
            .setPdxPersistent(true).build();
    serverLauncher.start();

    Cache cache = CacheFactory.getAnyInstance();

    cache.createDiskStoreFactory().setDiskDirsAndSizes(new File[] {pdxDirectory}, new int[] {16000})
        .create("pdxDS");

    cache.createDiskStoreFactory()
        .setDiskDirsAndSizes(new File[] {diskStoreDirectory}, new int[] {16000})
        .create("diskStore");

    RegionFactory<Object, Object> regionFactory = cache.createRegionFactory();
    regionFactory.setDataPolicy(DataPolicy.PERSISTENT_REPLICATE).setScope(Scope.DISTRIBUTED_ACK)
        .setDiskStoreName("diskStore").create("TestRegion");
  }


}
