#pragma once

#ifndef GEODE_GFCPP_POOLFACTORY_H_
#define GEODE_GFCPP_POOLFACTORY_H_

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

#include "gfcpp_globals.hpp"
#include "SharedBase.hpp"
#include "gf_types.hpp"
#include "Pool.hpp"

/**
 * @file
 */

namespace apache {
namespace geode {
namespace client {

class CacheImpl;
class PoolAttributes;

/**
 * This interface provides for the configuration and creation of instances of
 * {@link Pool}.
 * <p>Every pool needs to have at least one {@link #addLocator locator} or
 * {@link #addServer server} added
 * to it. Locators should be added unless direct connections to
 * bridge servers are desired.
 * <p>The setter methods are used to specify
 * non-default values for the other pool properties.
 * <p>Once it is configured {@link #create}
 * will produce an instance.
 * <p>The factory can be restored to its default
 * configuration by calling {@link #reset}.
 * <p>Instances of this interface can be created by calling
 * {@link Cache#getPoolFactory}.
 * <p>
 * If a subscription is going to be made using a pool then subscriptions
 * {@link #setSubscriptionEnabled must be enabled} on the pool.
 * Subscriptions are made using these APIs:
 * <ul>
 * <li>{@link QueryService#newCq}
 * <li>{@link Region#registerKeys}
 * <li>{@link Region#registerAllKeys}
 * <li>{@link Region#registerRegex}
 * </ul>
 *
 */
class CPPCACHE_EXPORT PoolFactory : public SharedBase {
 public:
  /**
   * The default amount of time, in milliseconds, which we will wait for a free
   * connection if max connections is set and all of the connections are in use.
   * <p>Current value: <code>10000</code>.
   */
  static const int DEFAULT_FREE_CONNECTION_TIMEOUT = 10000;

  /**
   * The default interval in which the pool will check to see if
   * a connection to a given server should be moved to a different
   * server to improve the load balance.
   * <p>Current value: <code>300,000</code> (which is 5 minutes).
   */
  static const int DEFAULT_LOAD_CONDITIONING_INTERVAL = 1000 * 60 * 5;

  /**
   * The default size in bytes of the socket buffer on each connection
   * established.
   * <p>Current value: <code>32768</code>.
   */
  static const int DEFAULT_SOCKET_BUFFER_SIZE = 32768;

  /**
   * The default amount of time, in milliseconds, to wait for a response from a
   * server.
   * <p>Current value: <code>10000</code>.
   */
  static const int DEFAULT_READ_TIMEOUT = 10000;

  /**
   * The default number of connections to be created initially.
   * <p>Current value: <code>1</code>.
   */
  static const int DEFAULT_MIN_CONNECTIONS = 1;

  /**
   * The default maximum number of connections to be created.
   * <p>Current value: <code>-1</code>.
   */
  static const int DEFAULT_MAX_CONNECTIONS = -1;

  /**
   * The default amount of time in milliseconds, to wait for a connection to
   * become idle.
   * <p>Current value: <code>5000</code>.
   */
  static const long DEFAULT_IDLE_TIMEOUT = 5000;

  /**
   * The default number of times to retry an operation after a timeout or
   * exception.
   * <p>Current value: <code>-1</code>.
   */
  static const int DEFAULT_RETRY_ATTEMPTS = -1;

  /**
   * The default frequency, in milliseconds, to ping servers.
   * <p>Current value: <code>10000</code>.
   */
  static const long DEFAULT_PING_INTERVAL = 10000;

  /**
   * The default frequency, in milliseconds, to update the locator list.
   * <p>Current value: <code>10000</code>.
   */
  static const long DEFAULT_UPDATE_LOCATOR_LIST_INTERVAL = 5000;

  /**
   * The default frequency, in milliseconds, that client statistics
   * are sent to the server.
   * <p>Current value: <code>-1</code>.
   */
  static const int DEFAULT_STATISTIC_INTERVAL = -1;

  /**
   * The default value for whether connections should have affinity to the
   * thread
   * that last used them.
   * <p>Current value: <code>false</code>.
   */
  // static const bool DEFAULT_THREAD_LOCAL_CONNECTIONS = false;

  /**
   * The default value for whether to establish a server to client subscription.
   * <p>Current value: <code>false</code>.
   */
  static const bool DEFAULT_SUBSCRIPTION_ENABLED = false;

  /**
   * The default redundancy for servers holding subscriptions established by
   * this
   * client.
   * <p>Current value: <code>0</code>.
   */
  static const int DEFAULT_SUBSCRIPTION_REDUNDANCY = 0;

  /**
   * The default amount of time, in milliseconds, that messages sent from a
   * server to a client will be tracked. The tracking is done to minimize
   * duplicate events.
   * <p>Current value: <code>900000</code>.
   */
  static const int DEFAULT_SUBSCRIPTION_MESSAGE_TRACKING_TIMEOUT = 900000;

  /**
   * The default amount of time, in milliseconds, to wait before
   * sending an acknowledgement to the server about events
   * received from the subscriptions.
   * <p>Current value: <code>100</code>.
   */
  static const int DEFAULT_SUBSCRIPTION_ACK_INTERVAL = 100;

  /**
   * The default server group.
   * <p>Current value: <code>""</code>.
   */
  static const char* DEFAULT_SERVER_GROUP;
  /**
   * Whether thread local connection is enabled.
   * <p>Current value: <code>"false"</code>.
   */
  static const bool DEFAULT_THREAD_LOCAL_CONN = false;

  /**
   * Whether client is in multi user secure mode
   * <p>Current value: <code>"false"</code>.
   */
  static const bool DEFAULT_MULTIUSER_SECURE_MODE = false;

  /**
   * The default value for whether to have single hop optimisations enabled.
   * <p>Current value: <code>true</code>.
   */
  static const bool DEFAULT_PR_SINGLE_HOP_ENABLED = true;

  /**
   * Sets the free connection timeout for this pool.
   * If the pool has a max connections setting, operations will block
   * if all of the connections are in use. The free connection timeout
   * specifies how long those operations will block waiting for
   * a free connection before receiving
   * an {@link AllConnectionsInUseException}. If max connections
   * is not set this setting has no effect.
   * @see #setMaxConnections(int)
   * @param connectionTimeout is the connection timeout in milliseconds
   * @return a reference to <code>this</code>
   * @throws IllegalArgumentException if <code>connectionTimeout</code>
   * is less than or equal to <code>0</code>.
   */
  void setFreeConnectionTimeout(int connectionTimeout);
  /**
   * Sets the load conditioning interval for this pool.
   * This interval controls how frequently the pool will check to see if
   * a connection to a given server should be moved to a different
   * server to improve the load balance.
   * <p>A value of <code>-1</code> disables load conditioning
   * @param loadConditioningInterval is the connection lifetime in milliseconds
   * @return a reference to <code>this</code>
   * @throws IllegalArgumentException if <code>connectionLifetime</code>
   * is less than <code>-1</code>.
   */
  void setLoadConditioningInterval(int loadConditioningInterval);
  /**
   * Sets the socket buffer size for each connection made in this pool.
   * Large messages can be received and sent faster when this buffer is larger.
   * Larger buffers also optimize the rate at which servers can send events
   * for client subscriptions.
   * @param bufferSize is the size of the socket buffers used for reading and
   * writing on each connection in this pool.
   * @return a reference to <code>this</code>
   * @throws IllegalArgumentException if <code>bufferSize</code>
   * is less than or equal to <code>0</code>.
   */
  void setSocketBufferSize(int bufferSize);

  /**
   * Sets the thread local connections policy for this pool.
   * If <code>true</code> then any time a thread goes to use a connection
   * from this pool it will check a thread local cache and see if it already
   * has a connection in it. If so it will use it. If not it will get one from
   * this pool and cache it in the thread local. This gets rid of thread
   * contention
   * for the connections but increases the number of connections the servers
   * see.
   * <p>If <code>false</code> then connections are returned to the pool as soon
   * as the operation being done with the connection completes. This allows
   * connections to be shared amonst multiple threads keeping the number of
   * connections down.
   * @param threadLocalConnections if <code>true</code> then enable thread local
   * connections.
   * @return a reference to <code>this</code>
   */
  void setThreadLocalConnections(bool threadLocalConnections);

  /**
   * Sets the number of milliseconds to wait for a response from a server before
   * timing out the operation and trying another server (if any are available).
   * @param timeout is the number of milliseconds to wait for a response from a
   * server
   * @return a reference to <code>this</code>
   * @throws IllegalArgumentException if <code>timeout</code>
   * is less than or equal to <code>0</code>.
   */
  void setReadTimeout(int timeout);

  /**
   * Sets the minimum number of connections to keep available at all times.
   * When the pool is created, it will create this many connections.
   * If <code>0</code> then connections will not be made until an actual
   * operation
   * is done that requires client-to-server communication.
   * @param minConnections is the initial number of connections
   * this pool will create.
   * @return a reference to <code>this</code>
   * @throws IllegalArgumentException if <code>minConnections</code>
   * is less than <code>0</code>.
   */
  void setMinConnections(int minConnections);

  /**
   * Sets the max number of client to server connections that the pool will
   * create. If all of
   * the connections are in use, an operation requiring a client to server
   * connection
   * will block until a connection is available.
   * @see #setFreeConnectionTimeout(int)
   * @param maxConnections is the maximum number of connections in the pool.
   * <code>-1</code> indicates that there is no maximum number of connections
   * @return a reference to <code>this</code>
   * @throws IllegalArgumentException if <code>maxConnections</code>
   * is less than <code>minConnections</code>.
   */
  void setMaxConnections(int maxConnections);

  /**
   * Sets the amount of time a connection can be idle before expiring the
   * connection.
   * If the pool size is greater than the minimum specified by
   * {@link PoolFactory#setMinConnections(int)}, connections which have been
   * idle
   * for longer than the idleTimeout will be closed.
   * @param idleTimeout is the amount of time in milliseconds that an idle
   * connection
   * should live before expiring. -1 indicates that connections should never
   * expire.
   * @return a reference to <code>this</code>
   * @throws IllegalArgumentException if <code>idleTimout</code>
   * is less than <code>0</code>.
   */
  void setIdleTimeout(long idleTimeout);

  /**
   * Set the number of times to retry a request after timeout/exception.
   * @param retryAttempts is the number of times to retry a request
   * after timeout/exception. -1 indicates that a request should be
   * tried against every available server before failing
   * @return a reference to <code>this</code>
   * @throws IllegalArgumentException if <code>idleTimout</code>
   * is less than <code>0</code>.
   */
  void setRetryAttempts(int retryAttempts);

  /**
   * The frequency with which servers must be pinged to verify that they are
   * still alive.
   * Each server will be sent a ping every <code>pingInterval</code> if there
   * has not
   * been any other communication with the server.
   *
   * These pings are used by the server to monitor the health of
   * the client. Make sure that the <code>pingInterval</code> is less than the
   * maximum time between pings allowed by the bridge server.
   * @param pingInterval is the amount of time in milliseconds between
   * pings.
   * @return a reference to <code>this</code>
   * @throws IllegalArgumentException if <code>pingInterval</code>
   * is less than <code>0</code>.
   * @see CacheServer#setMaximumTimeBetweenPings(int)
   */
  void setPingInterval(long pingInterval);

  /**
   * The frequency with which client updates the locator list. To disable this
   * set its
   * value to 0.
   * @param updateLocatorListInterval is the amount of time in milliseconds
   * between
   * checking locator list at locator.
   */
  void setUpdateLocatorListInterval(long updateLocatorListInterval);

  /**
   * The frequency with which the client statistics must be sent to the server.
   * Doing this allows <code>GFMon</code> to monitor clients.
   * <p>A value of <code>-1</code> disables the sending of client statistics
   * to the server.
   *
   * @param statisticInterval is the amount of time in milliseconds between
   * sends of client statistics to the server.
   * @return a reference to <code>this</code>
   * @throws IllegalArgumentException if <code>statisticInterval</code>
   * is less than <code>-1</code>.
   */
  void setStatisticInterval(int statisticInterval);

  /**
   * Configures the group which contains all the servers that this pool connects
   * to.
   * @param group is the server group that this pool will connect to.
   * If the value is <code>null</code> or <code>""</code> then the pool connects
   * to all servers.
   * @return a reference to <code>this</code>
   */
  void setServerGroup(const char* group);

  /**
   * Adds a locator, given its host and port, to this factory.
   * The locator must be a server locator and will be used to discover other
   * running
   * bridge servers and locators.
   * @param host is the host name or ip address that the locator is listening
   * on.
   * @param port is the port that the locator is listening on.
   * @return a reference to <code>this</code>
   * @throws IllegalArgumentException if the <code>host</code> is an unknown
   * host
   * according to {@link java.net.InetAddress#getByName} or if the port is
   * outside
   * the valid range of [1..65535] inclusive.
   * @throws IllegalStateException if the locator has already been {@link
   * #addServer added} to this factory.
   */
  void addLocator(const char* host, int port);

  /**
   * Adds a server, given its host and port, to this factory.
   * The server must be a bridge server and this client will
   * directly connect to the server without consulting a server locator.
   * @param host is the host name or ip address that the server is listening on.
   * @param port is the port that the server is listening on.
   * @return a reference to <code>this</code>
   * @throws IllegalArgumentException if the <code>host</code> is an unknown
   * host
   * according to {@link java.net.InetAddress#getByName} or if the port is
   * outside
   * the valid range of [1..65535] inclusive.
   * @throws IllegalStateException if the server has already been {@link
   * #addLocator added} to this factory.
   */
  void addServer(const char* host, int port);

  /**
   * If set to <code>true</code> then the created pool will have
   * server-to-client
   * subscriptions enabled.
   * If set to <code>false</code> then all <code>Subscription*</code> attributes
   * are ignored at the time of creation.
   * @return a reference to <code>this</code>
   */
  void setSubscriptionEnabled(bool enabled);
  /**
   * Sets the redundancy level for this pools server-to-client subscriptions.
   * If <code>0</code> then no redundant copies are kept on the servers.
   * Otherwise an effort is made to maintain the requested number of
   * copies of the server-to-client subscriptions. At most, one copy per server
   * is
   *  made up to the requested level.
   * @param redundancy is the number of redundant servers for this client's
   * subscriptions.
   * @return a reference to <code>this</code>
   * @throws IllegalArgumentException if <code>redundancyLevel</code>
   * is less than <code>-1</code>.
   */
  void setSubscriptionRedundancy(int redundancy);
  /**
   * Sets the messageTrackingTimeout attribute which is the time-to-live period,
   * in
   * milliseconds, for subscription events the client has received from the
   * server. It is used
   * to minimize duplicate events.
   * Entries that have not been modified for this amount of time
   * are expired from the list.
   * @param messageTrackingTimeout is the number of milliseconds to set the
   * timeout to.
   * @return a reference to <code>this</code>
   * @throws IllegalArgumentException if <code>messageTrackingTimeout</code>
   * is less than or equal to <code>0</code>.
   */
  void setSubscriptionMessageTrackingTimeout(int messageTrackingTimeout);

  /**
   * Sets the is the interval in milliseconds
   * to wait before sending acknowledgements to the bridge server for
   * events received from the server subscriptions.
   *
   * @param ackInterval is the number of milliseconds to wait before sending
   * event
   * acknowledgements.
   * @return a reference to <code>this</code>
   * @throws IllegalArgumentException if <code>ackInterval</code>
   * is less than or equal to <code>0</code>.
   */
  void setSubscriptionAckInterval(int ackInterval);

  /**
   * Sets whether Pool is in multi user secure mode.
   * If its in multiuser mode then app needs to get RegionService instance of
   * Cache.
   * Deafult value is false.
   */
  void setMultiuserAuthentication(bool multiuserAuthentication);

  /**
   * Resets the configuration of this factory to its defaults.
   * @return a reference to <code>this</code>
   */
  void reset();

  /**
   * Creates a new Pool for connecting a client to a set of Geode Cache
   * Servers.
   * using this factory's settings for attributes.
   *
   * @param name is the name of the pool, used when connecting regions to it
   * @throws IllegalStateException if a pool with <code>name</code> already
   * exists
   * @throws IllegalStateException if a locator or server has not been added.
   * @return the newly created pool.
   */
  PoolPtr create(const char* name);

  /**
   * By default setPRSingleHopEnabled is true<br>
   * The client is aware of location of partitions on servers hosting
   * {@link Region}s.
   * Using this information, the client routes the client cache operations
   * directly to the server which is hosting the required partition for the
   * cache operation.
   * If setPRSingleHopEnabled is false the client can do an extra hop on servers
   * to go to the required partition for that cache operation.
   * The setPRSingleHopEnabled avoids extra hops only for following cache
   * operations:<br>
   * 1. {@link Region#put(Object, Object)}<br>
   * 2. {@link Region#get(Object)}<br>
   * 3. {@link Region#destroy(Object)}<br>
   * If true, works best when {@link PoolFactory#setMaxConnections(int)} is set
   * to -1.
   * @param name is boolean whether PR Single Hop optimization is enabled or
   * not.
   * @return a reference to <code>this</code>
   */
  void setPRSingleHopEnabled(bool enabled);

  ~PoolFactory();

 private:
  PoolFactory();
  PoolFactory(const PoolFactory&);
  void addCheck(const char* host, int port);
  PoolAttributesPtr m_attrs;
  bool m_isSubscriptionRedundancy;
  bool m_addedServerOrLocator;
  friend class Cache;
  friend class PoolManager;
  friend class CacheFactory;
  friend class CacheXmlCreation;
};
}  // namespace client
}  // namespace geode
}  // namespace apache

#endif // GEODE_GFCPP_POOLFACTORY_H_
