/*
 * 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.modules.session.internal.common;

import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpSession;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import org.apache.geode.cache.GemFireCache;
import org.apache.geode.cache.InterestResultPolicy;
import org.apache.geode.cache.Region;
import org.apache.geode.cache.RegionShortcut;
import org.apache.geode.cache.client.ClientCache;
import org.apache.geode.cache.client.ClientRegionFactory;
import org.apache.geode.cache.client.ClientRegionShortcut;
import org.apache.geode.cache.execute.Execution;
import org.apache.geode.cache.execute.FunctionService;
import org.apache.geode.cache.execute.ResultCollector;
import org.apache.geode.modules.util.BootstrappingFunction;
import org.apache.geode.modules.util.CreateRegionFunction;
import org.apache.geode.modules.util.RegionConfiguration;
import org.apache.geode.modules.util.RegionStatus;
import org.apache.geode.modules.util.SessionCustomExpiry;

/**
 * Class which defines a client/server cache.
 */
public class ClientServerSessionCache extends AbstractSessionCache {

  private static final Logger LOG = LoggerFactory.getLogger(PeerToPeerSessionCache.class.getName());

  private ClientCache cache;

  protected static final String DEFAULT_REGION_ATTRIBUTES_ID =
      RegionShortcut.PARTITION_REDUNDANT.toString();

  protected static final Boolean DEFAULT_ENABLE_LOCAL_CACHE = true;

  /**
   * Constructor
   *
   */
  public ClientServerSessionCache(ClientCache cache, Map<CacheProperty, Object> properties) {
    super();
    this.cache = cache;

    /**
     * Set some default properties for this cache if they haven't already been set
     */
    this.properties.put(CacheProperty.REGION_ATTRIBUTES_ID, DEFAULT_REGION_ATTRIBUTES_ID);
    this.properties.put(CacheProperty.ENABLE_LOCAL_CACHE, DEFAULT_ENABLE_LOCAL_CACHE);
    this.properties.putAll(properties);
  }

  @Override
  public void initialize() {
    // Bootstrap the servers
    bootstrapServers();

    // Create or retrieve the region
    createOrRetrieveRegion();

    // Set the session region directly as the operating region since there is no difference
    // between the local cache region and the session region.
    operatingRegion = sessionRegion;

    // Create or retrieve the statistics
    createStatistics();
  }

  @Override
  public GemFireCache getCache() {
    return cache;
  }

  @Override
  public boolean isClientServer() {
    return true;
  }


  ////////////////////////////////////////////////////////////////////////
  // Private methods

  private void bootstrapServers() {
    Execution execution = FunctionService.onServers(this.cache);
    ResultCollector collector = execution.execute(new BootstrappingFunction());
    // Get the result. Nothing is being done with it.
    try {
      collector.getResult();
    } catch (Exception e) {
      // If an exception occurs in the function, log it.
      LOG.warn("Caught unexpected exception:", e);
    }
  }

  private void createOrRetrieveRegion() {
    // Retrieve the local session region
    this.sessionRegion = this.cache.getRegion((String) properties.get(CacheProperty.REGION_NAME));

    // If necessary, create the regions on the server and client
    if (this.sessionRegion == null) {
      // Create the PR on the servers
      createSessionRegionOnServers();

      // Create the region on the client
      this.sessionRegion = createLocalSessionRegion();
      LOG.debug("Created session region: " + this.sessionRegion);
    } else {
      LOG.debug("Retrieved session region: " + this.sessionRegion);

      // Register interest in case users provide their own client cache region
      sessionRegion.registerInterestForAllKeys(InterestResultPolicy.KEYS);
    }
  }

  private void createSessionRegionOnServers() {
    // Create the RegionConfiguration
    RegionConfiguration configuration = createRegionConfiguration();

    // Send it to the server tier
    Execution execution = FunctionService.onServer(this.cache).setArguments(configuration);
    ResultCollector collector = execution.execute(CreateRegionFunction.ID);

    // Verify the region was successfully created on the servers
    List<RegionStatus> results = (List<RegionStatus>) collector.getResult();
    for (RegionStatus status : results) {
      if (status == RegionStatus.INVALID) {
        StringBuilder builder = new StringBuilder();
        builder.append(
            "An exception occurred on the server while attempting to create or validate region named ");
        builder.append(properties.get(CacheProperty.REGION_NAME));
        builder.append(". See the server log for additional details.");
        throw new IllegalStateException(builder.toString());
      }
    }
  }

  private Region<String, HttpSession> createLocalSessionRegion() {
    ClientRegionFactory<String, HttpSession> factory = null;
    boolean enableLocalCache = (Boolean) properties.get(CacheProperty.ENABLE_LOCAL_CACHE);

    String regionName = (String) properties.get(CacheProperty.REGION_NAME);
    if (enableLocalCache) {
      // Create the region factory with caching and heap LRU enabled
      factory = this.cache
          .<String, HttpSession>createClientRegionFactory(
              ClientRegionShortcut.CACHING_PROXY_HEAP_LRU)
          .setCustomEntryIdleTimeout(new SessionCustomExpiry());
      LOG.info("Created new local client session region: {}", regionName);
    } else {
      // Create the region factory without caching enabled
      factory = this.cache.createClientRegionFactory(ClientRegionShortcut.PROXY);
      LOG.info("Created new local client (uncached) session region: {} without any session expiry",
          regionName);
    }

    // Create the region
    Region region = factory.create(regionName);

    region.registerInterestForAllKeys(InterestResultPolicy.KEYS);
    return region;
  }
}
